Test serializing booleans
assert(serializeMsgpack(true) == [0xc3]); assert(serializeMsgpack(false) == [0xc2]);
Test serializing nulls
assert(serializeMsgpack(null) == [0xc0]);
Test serializing signed integral types
// Bytes assert(serializeMsgpack(byte.min) == [0xd0, 0x80]); assert(serializeMsgpack(byte.max) == [0x7f]); // Shorts assert(serializeMsgpack(short(byte.max)) == [0x7f]); assert(serializeMsgpack(short(byte.max) + 1) == [0xd1, 0x00, 0x80]); assert(serializeMsgpack(short.min) == [0xd1, 0x80, 0x00]); assert(serializeMsgpack(short.max) == [0xd1, 0x7f, 0xff]); // Integers assert(serializeMsgpack(int(-32)) == [0xe0]); assert(serializeMsgpack(int(byte.max)) == [0x7f]); assert(serializeMsgpack(int(short.max)) == [0xd1, 0x7f, 0xff]); assert(serializeMsgpack(int(short.max) + 1) == [0xd2, 0x00, 0x00, 0x80, 0x00]); assert(serializeMsgpack(int.min) == [0xd2, 0x80, 0x00, 0x00, 0x00]); assert(serializeMsgpack(int.max) == [0xd2, 0x7f, 0xff, 0xff, 0xff]); // Long integers assert(serializeMsgpack(long(int.max)) == [0xd2, 0x7f, 0xff, 0xff, 0xff]); assert(serializeMsgpack(long(int.max) + 1) == [0xd3, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00]); assert(serializeMsgpack(long.max) == [0xd3, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]); assert(serializeMsgpack(long.min) == [0xd3, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
Test serializing unsigned integral types
// Unsigned bytes assert(serializeMsgpack(ubyte.min) == [0x00]); assert(serializeMsgpack(ubyte((1 << 7) - 1)) == [0x7f]); assert(serializeMsgpack(ubyte((1 << 7))) == [0xcc, 0x80]); assert(serializeMsgpack(ubyte.max) == [0xcc, 0xff]); // Unsigned shorts assert(serializeMsgpack(ushort(ubyte.max)) == [0xcc, 0xff]); assert(serializeMsgpack(ushort(ubyte.max + 1)) == [0xcd, 0x01, 0x00]); assert(serializeMsgpack(ushort.min) == [0x00]); assert(serializeMsgpack(ushort.max) == [0xcd, 0xff, 0xff]); // Unsigned integers assert(serializeMsgpack(uint(ubyte.max)) == [0xcc, 0xff]); assert(serializeMsgpack(uint(ushort.max)) == [0xcd, 0xff, 0xff]); assert(serializeMsgpack(uint(ushort.max + 1)) == [0xce, 0x00, 0x01, 0x00, 0x00]); assert(serializeMsgpack(uint.min) == [0x00]); assert(serializeMsgpack(uint.max) == [0xce, 0xff, 0xff, 0xff, 0xff]); // Long unsigned integers assert(serializeMsgpack(ulong(ubyte.max)) == [0xcc, 0xff]); assert(serializeMsgpack(ulong(ushort.max)) == [0xcd, 0xff, 0xff]); assert(serializeMsgpack(ulong(uint.max)) == [0xce, 0xff, 0xff, 0xff, 0xff]); assert(serializeMsgpack(ulong(uint.max) + 1) == [0xcf, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00]); assert(serializeMsgpack(ulong.min) == [0x00]); assert(serializeMsgpack(ulong.max) == [0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]); // Mir's BigIntView import mir.bignum.integer : BigInt; assert(serializeMsgpack(BigInt!2(0xDEADBEEF)) == [0xd3, 0x00, 0x00, 0x00, 0x00, 0xde, 0xad, 0xbe, 0xef]);
Test serializing floats / doubles / reals
import mir.test; assert(serializeMsgpack(float.min_normal) == [0xca, 0x00, 0x80, 0x00, 0x00]); assert(serializeMsgpack(float.max) == [0xca, 0x7f, 0x7f, 0xff, 0xff]); assert(serializeMsgpack(double.min_normal) == [0xcb, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]); assert(serializeMsgpack(double.max) == [0xcb, 0x7f, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]); static if (real.mant_dig == 64) { assert(serializeMsgpack(real.min_normal) == [0xcb,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00]); assert(serializeMsgpack(real.max) == [0xcb,0x7f,0xf0,0x00,0x00,0x00,0x00,0x00,0x00]); } // Mir's Decimal import mir.bignum.decimal : Decimal; serializeMsgpack(Decimal!2("777.777")).should == [0xcb,0x40,0x88,0x4e,0x37,0x4b,0xc6,0xa7,0xf0]; serializeMsgpack(Decimal!2("-777.7")).should == [0xcb,0xc0,0x88,0x4d,0x99,0x99,0x99,0x99,0x9a];
Test serializing timestamps
import mir.timestamp : Timestamp; assert(serializeMsgpack(Timestamp(1970, 1, 1, 0, 0, 0)) == [0xd6, 0xff, 0x00, 0x00, 0x00, 0x00]); assert(serializeMsgpack(Timestamp(2038, 1, 19, 3, 14, 7)) == [0xd6, 0xff, 0x7f, 0xff, 0xff, 0xff]); assert(serializeMsgpack(Timestamp(2299, 12, 31, 23, 59, 59)) == [0xd7, 0xff, 0x00, 0x00, 0x00, 0x02, 0x6c, 0xb5, 0xda, 0xff]); assert(serializeMsgpack(Timestamp(3000, 12, 31, 23, 59, 59)) == [0xc7, 0x0c, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x93, 0x3f, 0xff, 0x7f]);
Test serializing strings
import std.array : replicate; assert(serializeMsgpack("a") == [0xa1, 0x61]); // These need to be trusted because we cast const(char)[] to ubyte[] (which is fine here!) () @trusted { auto a = "a".replicate(32); assert(serializeMsgpack(a) == cast(ubyte[])[0xd9, 0x20] ~ cast(ubyte[])a); } (); () @trusted { auto a = "a".replicate(ushort.max); assert(serializeMsgpack(a) == cast(ubyte[])[0xda, 0xff, 0xff] ~ cast(ubyte[])a); } (); () @trusted { auto a = "a".replicate(ushort.max + 1); assert(serializeMsgpack(a) == cast(ubyte[])[0xdb, 0x00, 0x01, 0x00, 0x00] ~ cast(ubyte[])a); } ();
Test serializing blobs / clobs
import mir.lob : Blob, Clob; import std.array : replicate; // Blobs // These need to be trusted because we cast const(char)[] to ubyte[] (which is fine here!) () @trusted { auto de = "\xde".replicate(32); assert(serializeMsgpack(Blob(cast(ubyte[])de)) == cast(ubyte[])[0xc4, 0x20] ~ cast(ubyte[])de); } (); () @trusted { auto de = "\xde".replicate(ushort.max); assert(serializeMsgpack(Blob(cast(ubyte[])de)) == cast(ubyte[])[0xc5, 0xff, 0xff] ~ cast(ubyte[])de); } (); () @trusted { auto de = "\xde".replicate(ushort.max + 1); assert(serializeMsgpack(Blob(cast(ubyte[])de)) == cast(ubyte[])[0xc6, 0x00, 0x01, 0x00, 0x00] ~ cast(ubyte[])de); } (); // Clobs (serialized just as regular strings here) () @trusted { auto de = "\xde".replicate(32); assert(serializeMsgpack(Clob(de)) == cast(ubyte[])[0xd9, 0x20] ~ cast(ubyte[])de); } ();
Test serializing arrays
// nested arrays assert(serializeMsgpack([["foo"], ["bar"], ["baz"]]) == [0x93, 0x91, 0xa3, 0x66, 0x6f, 0x6f, 0x91, 0xa3, 0x62, 0x61, 0x72, 0x91, 0xa3, 0x62, 0x61, 0x7a]); assert(serializeMsgpack([0xDEADBEEF, 0xCAFEBABE, 0xAAAA_AAAA]) == [0x93, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xce, 0xca, 0xfe, 0xba, 0xbe, 0xce, 0xaa, 0xaa, 0xaa, 0xaa]); assert(serializeMsgpack(["foo", "bar", "baz"]) == [0x93, 0xa3, 0x66, 0x6f, 0x6f, 0xa3, 0x62, 0x61, 0x72, 0xa3, 0x62, 0x61, 0x7a]); assert(serializeMsgpack([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17]) == [0xdc,0x00,0x11,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11]);
Test serializing enums
enum Foo { Bar, Baz } assert(serializeMsgpack(Foo.Bar) == [0xa3,0x42,0x61,0x72]); assert(serializeMsgpack(Foo.Baz) == [0xa3,0x42,0x61,0x7a]);
Test serializing maps (structs)
static struct Book { string title; bool wouldRecommend; string description; uint numberOfNovellas; double price; float weight; string[] tags; } Book book = Book("A Hero of Our Time", true, "", 5, 7.99, 6.88, ["russian", "novel", "19th century"]); // This will probably break if you modify how any of the data types // are serialized. assert(serializeMsgpack(book) == [0x87,0xa5,0x74,0x69,0x74,0x6c,0x65,0xb2,0x41,0x20,0x48,0x65,0x72,0x6f,0x20,0x6f,0x66,0x20,0x4f,0x75,0x72,0x20,0x54,0x69,0x6d,0x65,0xae,0x77,0x6f,0x75,0x6c,0x64,0x52,0x65,0x63,0x6f,0x6d,0x6d,0x65,0x6e,0x64,0xc3,0xab,0x64,0x65,0x73,0x63,0x72,0x69,0x70,0x74,0x69,0x6f,0x6e,0xa0,0xb0,0x6e,0x75,0x6d,0x62,0x65,0x72,0x4f,0x66,0x4e,0x6f,0x76,0x65,0x6c,0x6c,0x61,0x73,0x05,0xa5,0x70,0x72,0x69,0x63,0x65,0xcb,0x40,0x1f,0xf5,0xc2,0x8f,0x5c,0x28,0xf6,0xa6,0x77,0x65,0x69,0x67,0x68,0x74,0xca,0x40,0xdc,0x28,0xf6,0xa4,0x74,0x61,0x67,0x73,0x93,0xa7,0x72,0x75,0x73,0x73,0x69,0x61,0x6e,0xa5,0x6e,0x6f,0x76,0x65,0x6c,0xac,0x31,0x39,0x74,0x68,0x20,0x63,0x65,0x6e,0x74,0x75,0x72,0x79]);
Test serializing a large map (struct)
static struct HugeStruct { bool a; bool b; bool c; bool d; bool e; string f; string g; string h; string i; string j; int k; int l; int m; int n; int o; long p; } HugeStruct s = HugeStruct(true, true, true, true, true, "", "", "", "", "", 123, 456, 789, 123, 456, 0xDEADBEEF); assert(serializeMsgpack(s) == [0xde,0x00,0x10,0xa1,0x61,0xc3,0xa1,0x62,0xc3,0xa1,0x63,0xc3,0xa1,0x64,0xc3,0xa1,0x65,0xc3,0xa1,0x66,0xa0,0xa1,0x67,0xa0,0xa1,0x68,0xa0,0xa1,0x69,0xa0,0xa1,0x6a,0xa0,0xa1,0x6b,0x7b,0xa1,0x6c,0xd1,0x01,0xc8,0xa1,0x6d,0xd1,0x03,0x15,0xa1,0x6e,0x7b,0xa1,0x6f,0xd1,0x01,0xc8,0xa1,0x70,0xd3,0x00,0x00,0x00,0x00,0xde,0xad,0xbe,0xef]);
Test serializing annotated structs
import mir.algebraic; import mir.serde : serdeAlgebraicAnnotation; @serdeAlgebraicAnnotation("Foo") static struct Foo { string bar; } @serdeAlgebraicAnnotation("Fooz") static struct Fooz { long bar; } alias V = Variant!(Foo, Fooz); auto foo = V(Foo("baz")); assert(serializeMsgpack(foo) == [0x81,0xa3,0x46,0x6f,0x6f,0x81,0xa3,0x62,0x61,0x72,0xa3,0x62,0x61,0x7a]);
Test custom serialize function with MessagePack
static class MyExampleClass { string text; this(string text) { this.text = text; } void serialize(S)(scope ref S serializer) scope const { auto state = serializer.stringBegin; serializer.putStringPart("Hello! "); serializer.putStringPart("String passed: "); serializer.putStringPart(this.text); serializer.stringEnd(state); import mir.ion.type_code : IonTypeCode; serializer.putNull(IonTypeCode.string); } } assert(serializeMsgpack(new MyExampleClass("foo bar baz")) == [0xd9,0x21,0x48,0x65,0x6c,0x6c,0x6f,0x21,0x20,0x53,0x74,0x72,0x69,0x6e,0x67,0x20,0x70,0x61,0x73,0x73,0x65,0x64,0x3a,0x20,0x66,0x6f,0x6f,0x20,0x62,0x61,0x72,0x20,0x62,0x61,0x7a,0xc0]);