StringMap support
import mir.string_map; auto map = `{"b" : 1.0, "a" : 2}`.deserialize!(StringMap!double); assert(map.keys == ["b", "a"]); assert(map.values == [1.0, 2.0]); assert(map.serializeToJson == `{"b":1.0,"a":2.0}`);
JsonAlgebraic alias support
import mir.algebraic_alias.json; auto value = `{"b" : 1.0, "a" : [1, true, false, null, "str"]}`.deserialize!JsonAlgebraic; assert(value.kind == JsonAlgebraic.Kind.object); auto object = value.get!(StringMap!JsonAlgebraic); assert(object.keys == ["b", "a"]); // sequental order assert(object["b"].get!double == 1.0); object["b"].get!double += 4; auto array = object["a"].get!(JsonAlgebraic[]); assert(array[0].get!long == 1); array[0].get!long += 10; assert(array[1].get!bool == true); assert(array[2].get!bool == false); assert(array[3].isNull); assert(array[3].get!(typeof(null)) is null); assert(array[4].get!string == "str"); assert(value.serializeToJson == `{"b":5.0,"a":[11,true,false,null,"str"]}`); value = [JsonAlgebraic[].init.JsonAlgebraic, StringMap!JsonAlgebraic.init.JsonAlgebraic, string.init.JsonAlgebraic]; // algebraics have type safe serialization instead of null values assert(value.serializeToJson == `[[],{},""]`, value.serializeToJson);
User defined algebraic types deserialization supports any subset of the following types:
A StringMap has has priority over builtin associative arrays.
Serializations works with any algebraic types.
See_also: $(GMREF mir-core, mir,algebraic), $(GMREF mir-algorithm, mir,string_map)
import mir.algebraic: Nullable, This; // Nullable, Variant, or TaggedVariant alias MyJsonAlgebraic = Nullable!(bool, string, double[], This[string]); auto value = `{"b" : true, "z" : null, "this" : {"c" : "str", "d" : [1, 2, 3, 4]}}`.deserialize!MyJsonAlgebraic; auto object = value.get!(MyJsonAlgebraic[string]); assert(object["b"].get!bool == true); assert(object["z"].isNull); object = object["this"].get!(MyJsonAlgebraic[string]); assert(object["c"].get!string == "str"); assert(object["d"].get!(double[]) == [1.0, 2, 3, 4]);
static class Turtle { string _metadata; long id; string species; } auto turtles = ` [{"_metadata":"xyz123", "id":72, "species":"Galapagos"}, {"_metadata":"tu144", "id":108, "species":"Snapping"}, null, null, {"_metadata":"anew1", "id":9314, "species":"Sea Turtle"}]` .deserialize!(Turtle[]);
Alias this support
struct S { int a; } struct C { S s; alias s this; int b; } assert(`{"a":3, "b":4}`.deserialize!C == C(S(3), 4));
serdeOrderedIn supprot
static struct I { @serdeOptional int a; int m; } @serdeOrderedIn static struct S { import mir.small_string; SmallString!8 id; int acc; I inner = I(1000, 0); @safe pure nothrow @nogc @property: void add(int v) { inner.a += v; acc += v; } void mul(int v) { inner.m += v; acc *= v; } } import mir.reflection; auto val = `{"mul":2, "id": "str", "add":5,"acc":100, "inner":{"m": 2000}}`.deserialize!S; assert(val.id == "str"); assert(val.acc == 210); assert(val.inner.a == 1005); assert(val.inner.m == 2002); assert(val.serializeToJson == `{"id":"str","acc":210,"inner":{"a":1005,"m":2002}}`);
serdeRealOrderedIn supprot
static struct I { @serdeOptional int a; int m; } @serdeRealOrderedIn static struct S { import mir.small_string; SmallString!8 id; int acc; I inner = I(1000, 0); @safe pure nothrow @nogc @property: void add(int v) { inner.a += v; acc += v; } void mul(int v) { inner.m += v; acc *= v; } } import mir.reflection; auto val = `{"mul":2, "id": "str", "add":5,"acc":100, "inner":{"m": 2000}}`.deserialize!S; assert(val.id == "str"); assert(val.acc == 210); assert(val.inner.a == 1005); assert(val.inner.m == 2002); assert(val.serializeToJson == `{"id":"str","acc":210,"inner":{"a":1005,"m":2002}}`);
struct A { string str; } struct B { A a; string serialize() const { return asdf.serializeToJson(a); } } assert(B(A("2323")).serialize == `{"str":"2323"}`);
Deserialize aggregate value