Report a bug
If you spot a problem with this page, click here to create a GitHub issue.
Improve this page
Quickly fork, edit online, and submit a pull request for this page. Requires a signed-in GitHub account. This works well for small changes. If you'd like to make larger changes you may want to consider using a local clone.

mir.deser.msgpack

High level Msgpack deserialization API

struct MsgpackValueStream;
void deserializeMsgpack(T)(ref T value, scope const(ubyte)[] data);
Examples:
Test round-trip serialization/deserialization of signed integral types
import mir.ser.msgpack : serializeMsgpack;

// Bytes
assert(serializeMsgpack(byte.min).deserializeMsgpack!byte == byte.min);
assert(serializeMsgpack(byte.max).deserializeMsgpack!byte == byte.max);
assert(serializeMsgpack(byte(-32)).deserializeMsgpack!byte == -32);

// Shorts
assert(serializeMsgpack(short.min).deserializeMsgpack!short == short.min);
assert(serializeMsgpack(short.max).deserializeMsgpack!short == short.max);

// Integers
assert(serializeMsgpack(int.min).deserializeMsgpack!int == int.min);
assert(serializeMsgpack(int.max).deserializeMsgpack!int == int.max);

// Longs
assert(serializeMsgpack(long.min).deserializeMsgpack!long == long.min);
assert(serializeMsgpack(long.max).deserializeMsgpack!long == long.max);
Examples:
Test round-trip serialization/deserialization of unsigned integral types
import mir.ser.msgpack : serializeMsgpack;

// Unsigned bytes
assert(serializeMsgpack(ubyte.min).deserializeMsgpack!ubyte == ubyte.min);
assert(serializeMsgpack(ubyte.max).deserializeMsgpack!ubyte == ubyte.max);

// Unsigned shorts
assert(serializeMsgpack(ushort.min).deserializeMsgpack!ushort == ushort.min);
assert(serializeMsgpack(ushort.max).deserializeMsgpack!ushort == ushort.max);

// Unsigned integers
assert(serializeMsgpack(uint.min).deserializeMsgpack!uint == uint.min);
assert(serializeMsgpack(uint.max).deserializeMsgpack!uint == uint.max);

// Unsigned logns
assert(serializeMsgpack(ulong.min).deserializeMsgpack!ulong == ulong.min);
assert(serializeMsgpack(ulong.max).deserializeMsgpack!ulong == ulong.max);

// BigInt
import mir.bignum.integer : BigInt;
assert(serializeMsgpack(BigInt!2(0xDEADBEEF)).deserializeMsgpack!long == 0xDEADBEEF);
Examples:
Test round-trip serialization/deserialization of null
import mir.ser.msgpack : serializeMsgpack;

assert(serializeMsgpack(null).deserializeMsgpack!(typeof(null)) == null);
Examples:
Test round-trip serialization/deserialization of booleans
import mir.ser.msgpack : serializeMsgpack;

assert(serializeMsgpack(true).deserializeMsgpack!bool == true);
assert(serializeMsgpack(false).deserializeMsgpack!bool == false);
Examples:
Test round-trip serialization/deserialization of strings
import std.array : replicate;
import mir.ser.msgpack : serializeMsgpack;

assert("foobar".serializeMsgpack.deserializeMsgpack!string == "foobar");
assert("bazfoo".serializeMsgpack.deserializeMsgpack!string == "bazfoo");

{
    auto str = "a".replicate(32);
    assert(serializeMsgpack(str).deserializeMsgpack!string == str);
}

{
    auto str = "a".replicate(ushort.max);
    assert(serializeMsgpack(str).deserializeMsgpack!string == str);
}

{
    auto str = "a".replicate(ushort.max + 1);
    assert(serializeMsgpack(str).deserializeMsgpack!string == str);
}
Examples:
Test round-trip serializing/deserialization blobs / clobs
import mir.lob : Blob, Clob;
import mir.ser.msgpack : serializeMsgpack;
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);
    auto blob = Blob(cast(ubyte[])de);
    assert(serializeMsgpack(blob).deserializeMsgpack!Blob == blob);
} ();

() @trusted {
    auto de = "\xde".replicate(ushort.max);
    auto blob = Blob(cast(ubyte[])de);
    assert(serializeMsgpack(blob).deserializeMsgpack!Blob == blob);
} ();

() @trusted {
    auto de = "\xde".replicate(ushort.max + 1);
    auto blob = Blob(cast(ubyte[])de);
    assert(serializeMsgpack(blob).deserializeMsgpack!Blob == blob);
} ();

// Clobs (serialized just as regular strings here)
() @trusted {
    auto de = "\xde".replicate(32);
    auto clob = Clob(de);
    assert(serializeMsgpack(clob).deserializeMsgpack!string == clob.data);
} ();
Examples:
Test round-trip serialization/deserialization of arrays
import mir.ser.msgpack : serializeMsgpack;

{
    auto arr = [["foo"], ["bar"], ["baz"]];
    assert(serializeMsgpack(arr).deserializeMsgpack!(typeof(arr)) == arr);
}

{
    auto arr = [0xDEADBEEF, 0xCAFEBABE, 0xAAAA_AAAA];
    assert(serializeMsgpack(arr).deserializeMsgpack!(typeof(arr)) == arr);
}

{
    auto arr = ["foo", "bar", "baz"];
    assert(serializeMsgpack(arr).deserializeMsgpack!(typeof(arr)) == arr);
}

{
    auto arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17];
    assert(serializeMsgpack(arr).deserializeMsgpack!(typeof(arr)) == arr);
}
Examples:
Test serializing maps (structs)
import mir.ser.msgpack : serializeMsgpack;
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"]);

assert(serializeMsgpack(book).deserializeMsgpack!(Book) == book);
Examples:
Test serializing maps (structs), assuming @nogc
import mir.appender : scopedBuffer;
import mir.ser.msgpack : serializeMsgpack;
// import mir.small_string;

static struct Book
{
    // SmallStrings apparently cannot be serialized
    // without allocating?
    // SmallString!64 title;
    bool wouldRecommend;
    // SmallString!64 description;
    uint numberOfNovellas;
    double price;
    float weight;
}

auto buf = scopedBuffer!ubyte();
Book book = Book(true, 5, 7.99, 6.88);
serializeMsgpack((() @trusted => &buf)(), book);
assert(buf.data.deserializeMsgpack!Book() == book);
Examples:
Test round-trip serialization/deserialization of a large map
import mir.ser.msgpack : serializeMsgpack;
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).deserializeMsgpack!HugeStruct == s);
Examples:
Test excessively large array
import mir.ser.msgpack : serializeMsgpack;
static struct HugeArray
{
    ubyte[] arg;

    void serialize(S)(ref S serializer) const
    {
        auto state = serializer.structBegin();
        serializer.putKey("arg");
        auto arrayState = serializer.listBegin(); 
        foreach(i; 0 .. (ushort.max + 1))
        {
            serializer.elemBegin; serializer.putValue(ubyte(0));
        }
        serializer.listEnd(arrayState);
        serializer.structEnd(state);
    }
}

auto arr = HugeArray();
assert((serializeMsgpack(arr).deserializeMsgpack!HugeArray).arg.length == ushort.max + 1);
Examples:
Test excessively large map
import mir.serde : serdeAllowMultiple;
import mir.ser.msgpack : serializeMsgpack;
static struct BFM // Big Freakin' Map
{
    @serdeAllowMultiple
    ubyte asdf;

    void serialize(S)(ref S serializer) const
    {
        auto state = serializer.structBegin();
        foreach (i; 0 .. (ushort.max + 1))
        {
            serializer.putKey("asdf");
            serializer.putValue(ubyte(0));
        }
        serializer.structEnd(state);
    }
}

auto map = BFM();
assert(serializeMsgpack(map).deserializeMsgpack!BFM == map);
Examples:
Test map with varying key lengths
import mir.ser.msgpack : serializeMsgpack;
import std.array : replicate;
ubyte[string] map;
map["a".replicate(32)] = 0xFF;
map["b".replicate(ubyte.max + 1)] = 0xFF;
map["c".replicate(ushort.max + 1)] = 0xFF;

assert(serializeMsgpack(map).deserializeMsgpack!(typeof(map)) == map);
Examples:
Test deserializing an extension type
import mir.lob : Blob;

{
    const(ubyte)[] data = [0xc7, 0x01, 0x02, 0xff];
    MsgpackExtension ext = MsgpackExtension(Blob([0xff]), 0x02);
    assert(data.deserializeMsgpack!MsgpackExtension == ext);
}

{
    const(ubyte)[] data = [0xc8, 0x00, 0x01, 0x02, 0xff];
    MsgpackExtension ext = MsgpackExtension(Blob([0xff]), 0x02);
    assert(data.deserializeMsgpack!MsgpackExtension == ext);
}

{
    const(ubyte)[] data = [0xc9, 0x00, 0x00, 0x00, 0x01, 0x02, 0xff];
    MsgpackExtension ext = MsgpackExtension(Blob([0xff]), 0x02);
    assert(data.deserializeMsgpack!MsgpackExtension == ext);
}