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.
asdf.serialization
ASDF and JSON Serialization
For aggregate types the order of the (de)serialization is the folowing:
- All public fields of alias ? this that are not hidden by members of this (recursively).
- All public fields of this.
- All public properties of alias ? this that are not hidden by members of this (recursively).
- All public properties of this.
Examples:
import asdf; import std.bigint; import std.datetime; import mir.conv; enum E : char { a, b, c, } static class C { private double _foo; pure: this() { _foo = 4; } double foo() const @property { return _foo + 10; } void foo(double d) @property { _foo = d - 10; } } import mir.timestamp: Timestamp; static struct S { static int staticNotSeialised = 5; enum int enumsNotSeialised = 3; @serdeProxy!Timestamp DateTime time; C object; string[E] map; @serdeKeys("bar_common", "bar") string bar; } enum json = `{"time":"2016-03-04T00:00:00Z","object":{"foo":14.0},"map":{"a":"A"},"bar_common":"escaped chars = '\\', '\"', '\t', '\r', '\n'"}`; auto value = S( DateTime(2016, 3, 4), new C, [E.a : "A"], "escaped chars = '\\', '\"', '\t', '\r', '\n'"); assert(serializeToJson(cast(const)value) == json, serializeToJson(cast(const)value)); // check serialization of const data assert(serializeToAsdf(value).to!string == json, serializeToAsdf(value).to!string); assert(deserialize!S(json).serializeToJson == json);
Examples:
finalizeSerialization method
import asdf; static struct S { string a; int b; void finalizeSerialization(Serializer)(ref Serializer serializer) { serializer.putKey("c"); serializer.putValue(100); } } assert(S("bar", 3).serializeToJson == `{"a":"bar","b":3,"c":100}`);
Examples:
finalizeDeserialization method
import asdf; static struct S { string a; int b; @serdeIgnoreIn double sum; void finalizeDeserialization(Asdf data) pure { auto r = data["c", "d"]; auto a = r["e"].get(0.0); auto b = r["g"].get(0.0); sum = a + b; } void serdeFinalize() pure { sum *= 2; } } assert(`{"a":"bar","b":3,"c":{"d":{"e":6,"g":7}}}`.deserialize!S == S("bar", 3, 26));
Examples:
A user may define setter and/or getter properties.
import asdf; import mir.conv: to; static struct S { @serdeIgnore string str; pure: string a() @property { return str; } void b(int s) @property { str = s.to!string; } } assert(S("str").serializeToJson == `{"a":"str"}`); assert(`{"b":123}`.deserialize!S.str == "123");
Examples:
Support for custom nullable types (types that has a bool property isNull,
non-void property get returning payload and void property nullify that
makes nullable type to null value)
import asdf; static struct MyNullable { long value; @property isNull() const { return value == 0; } @property get() { return value; } @property nullify() { value = 0; } auto opAssign(long value) { this.value = value; } } static struct Foo { MyNullable my_nullable; string field; bool opEquals()(auto ref const(typeof(this)) rhs) { if (my_nullable.isNull && rhs.my_nullable.isNull) return field == rhs.field; if (my_nullable.isNull != rhs.my_nullable.isNull) return false; return my_nullable == rhs.my_nullable && field == rhs.field; } } Foo foo; foo.field = "it's a foo"; assert (serializeToJson(foo) == `{"my_nullable":null,"field":"it's a foo"}`); foo.my_nullable = 200; assert (deserialize!Foo(`{"my_nullable":200,"field":"it's a foo"}`) == Foo(MyNullable(200), "it's a foo")); import std.typecons : Nullable; static struct Bar { Nullable!long nullable; string field; bool opEquals()(auto ref const(typeof(this)) rhs) { if (nullable.isNull && rhs.nullable.isNull) return field == rhs.field; if (nullable.isNull != rhs.nullable.isNull) return false; return nullable == rhs.nullable && field == rhs.field; } } Bar bar; bar.field = "it's a bar"; assert (serializeToJson(bar) == `{"nullable":null,"field":"it's a bar"}`); bar.nullable = 777; assert (deserialize!Bar(`{"nullable":777,"field":"it's a bar"}`) == Bar(Nullable!long(777), "it's a bar")); static struct S { long i; SerdeException deserializeFromAsdf(Asdf data) { if (auto exc = deserializeValue(data, i)) return exc; return null; } } static struct T { // import std.typecons: Nullable; import mir.algebraic: Nullable; Nullable!S test; } T t = deserialize!T(`{ "test": 5 }`); assert(t.test.i == 5);
Examples:
Support for floating point nan and (partial) infinity
import mir.conv: to; import asdf; static struct Foo { float f; bool opEquals()(auto ref const(typeof(this)) rhs) { import std.math : isNaN, approxEqual; if (f.isNaN && rhs.f.isNaN) return true; return approxEqual(f, rhs.f); } } // test for Not a Number assert (serializeToJson(Foo()).to!string == `{"f":"nan"}`); assert (serializeToAsdf(Foo()).to!string == `{"f":"nan"}`); assert (deserialize!Foo(`{"f":null}`) == Foo()); assert (deserialize!Foo(`{"f":"nan"}`) == Foo()); assert (serializeToJson(Foo(1f/0f)).to!string == `{"f":"inf"}`); assert (serializeToAsdf(Foo(1f/0f)).to!string == `{"f":"inf"}`); assert (deserialize!Foo(`{"f":"inf"}`) == Foo( float.infinity)); assert (deserialize!Foo(`{"f":"-inf"}`) == Foo(-float.infinity)); assert (serializeToJson(Foo(-1f/0f)).to!string == `{"f":"-inf"}`); assert (serializeToAsdf(Foo(-1f/0f)).to!string == `{"f":"-inf"}`); assert (deserialize!Foo(`{"f":"-inf"}`) == Foo(-float.infinity));
- string
serializeToJson
(V)(auto ref Vvalue
); - JSON serialization function.Examples:
import asdf; struct S { string foo; uint bar; } assert(serializeToJson(S("str", 4)) == `{"foo":"str","bar":4}`);
- string
serializeToJsonPretty
(string sep = "\x09", V)(auto ref Vvalue
); - JSON serialization function with pretty formatting.Examples:
import asdf; static struct S { int a; } assert(S(4).serializeToJsonPretty == "{\n\t\"a\": 4\n}");
- void
serializeToJsonPretty
(string sep = "\x09", V, O)(auto ref Vvalue
, ref Ooutput
)
if (isOutputRange!(O, const(char)[])); - JSON serialization function with pretty formatting and custom output range.
- Asdf
serializeToAsdf
(V)(auto ref Vvalue
, size_tinitialLength
= 32); - ASDF serialization functionExamples:
import asdf; import mir.conv: to; struct S { string foo; uint bar; } assert(serializeToAsdf(S("str", 4)).to!string == `{"foo":"str","bar":4}`);
- V
deserialize
(V)(Asdfdata
);
Vdeserialize
(V)(in char[]str
); - Deserialization functionExamples:
struct S { string foo; uint bar; } assert(deserialize!S(`{"foo":"str","bar":4}`) == S("str", 4));
Examples:Proxy for membersstruct S { // const(char)[] doesn't reallocate ASDF data. @serdeProxy!(const(char)[]) uint bar; } auto json = `{"bar":"4"}`; assert(serializeToJson(S(4)) == json); assert(deserialize!S(json) == S(4));
- struct
JsonSerializer
(string sep, Dg); - JSON serialization back-end
- JsonBuffer!Dg
sink
; - JSON string buffer
- this(Dg
sink
); - uint
structBegin
(size_tlength
= 0);
voidstructEnd
(uintstate
);
uintlistBegin
(size_tlength
= 0);
voidlistEnd
(uintstate
);
voidputEscapedKey
(in char[]key
);
voidputKey
(in char[]key
);
voidputNumberValue
(Num)(Numnum
, FormatSpec!charfmt
= FormatSpec!char.init);
voidputValue
(typeof(null));
voidputValue
(boolb
);
voidputValue
(in char[]str
);
voidputValue
(Num)(Numnum
)
if (isNumeric!Num && !is(Num == enum));
voidelemBegin
();
voidflush
(); - Serialization primitives
- auto
jsonSerializer
(string sep = "", Dg)(scope Dgsink
); - Creates JSON serialization back-end. Use sep equal to "\t" or " " for pretty formatting.Examples:
import asdf; import std.array; import std.bigint; import std.format: singleSpec; auto app = appender!string; auto ser = jsonSerializer(&app.put!(const(char)[])); auto state0 = ser.structBegin; ser.putEscapedKey("null"); ser.putValue(null); ser.putEscapedKey("array"); auto state1 = ser.listBegin(); ser.elemBegin; ser.putValue(null); ser.elemBegin; ser.putValue(123); ser.elemBegin; ser.putNumberValue(12300000.123, singleSpec("%.10e")); ser.elemBegin; ser.putValue("\t"); ser.elemBegin; ser.putValue("\r"); ser.elemBegin; ser.putValue("\n"); ser.elemBegin; ser.putNumberValue(BigInt("1234567890")); ser.listEnd(state1); ser.structEnd(state0); ser.flush; assert(app.data == `{"null":null,"array":[null,123,1.2300000123e+07,"\t","\r","\n",1234567890]}`);
- struct
AsdfSerializer
; - ASDF serialization back-end
- OutputArray
app
; - Output buffer
- pure size_t
structBegin
(size_tlength
= 0);
pure voidstructEnd
(size_tstate
);
pure size_tlistBegin
(size_tlength
= 0);
pure voidlistEnd
(size_tstate
);
aliasputEscapedKey
= putKey;
pure voidputKey
(in char[]key
);
pure voidputNumberValue
(Num)(Numnum
, FormatSpec!charfmt
= FormatSpec!char.init);
pure voidputValue
(typeof(null));
pure voidputValue
(boolb
);
pure voidputValue
(in char[]str
);
voidputValue
(Num)(Numnum
)
if (isNumeric!Num && !is(Num == enum)); - Serialization primitives
- void
putValue
(Num)(const Numvalue
)
if (isNumeric!Num && !is(Num == enum));
static pure voidelemBegin
();
static pure voidflush
();
- auto
asdfSerializer
(size_tinitialLength
= 32); - Create ASDF serialization back-endExamples:
import asdf; import mir.conv: to; import std.bigint; import std.format: singleSpec; auto ser = asdfSerializer(); auto state0 = ser.structBegin; ser.putEscapedKey("null"); ser.putValue(null); ser.putKey("array"); auto state1 = ser.listBegin(); ser.elemBegin; ser.putValue(null); ser.elemBegin; ser.putValue(123); ser.elemBegin; ser.putNumberValue(12300000.123, singleSpec("%.10e")); ser.elemBegin; ser.putValue("\t"); ser.elemBegin; ser.putValue("\r"); ser.elemBegin; ser.putValue("\n"); ser.elemBegin; ser.putNumberValue(BigInt("1234567890")); ser.listEnd(state1); ser.structEnd(state0); assert(ser.app.result.to!string == `{"null":null,"array":[null,123,1.2300000123e+07,"\t","\r","\n",1234567890]}`);
- void
serializeValue
(S)(ref Sserializer
, typeof(null)); - null value serializationExamples:
import asdf; assert(serializeToJson(null) == `null`);
- void
serializeValue
(S, V)(ref Sserializer
, in Vvalue
, FormatSpec!charfmt
= FormatSpec!char.init)
if (isNumeric!V && !is(V == enum) || is(V == BigInt)); - Number serializationExamples:
import std.bigint; assert(serializeToJson(BigInt(123)) == `123`); assert(serializeToJson(2.40f) == `2.4`); assert(serializeToJson(float.nan) == `"nan"`); assert(serializeToJson(float.infinity) == `"inf"`); assert(serializeToJson(-float.infinity) == `"-inf"`);
- void
serializeValue
(S, V)(ref Sserializer
, const Vvalue
)
if (is(V == bool) && !is(V == enum)); - Boolean serialization
- void
serializeValue
(S, V : char)(ref Sserializer
, const Vvalue
)
if (is(V == char) && !is(V == enum)); - Char serializationExamples:
assert(serializeToJson(true) == `true`);
- void
serializeValue
(S, V)(ref Sserializer
, in Vvalue
)
if (is(V == enum)); - Enum serializationExamples:
enum Key { @serdeKeys("FOO", "foo") foo } assert(serializeToJson(Key.foo) == `"FOO"`);
- void
serializeValue
(S)(ref Sserializer
, in char[]value
); - String serializationExamples:
assert(serializeToJson("\t \" \\") == `"\t \" \\"`);
- void
serializeValue
(S, T)(ref Sserializer
, T[]value
)
if (!isSomeChar!T); - Array serialization
- void
serializeValue
(S, R)(ref Sserializer
, Rvalue
)
if (isInputRange!R && !isSomeChar!(ElementType!R) && !isDynamicArray!R && !isStdNullable!R); - Input range serializationExamples:input range serialization
import std.algorithm : filter; struct Foo { int i; } auto ar = [Foo(1), Foo(3), Foo(4), Foo(17)]; auto filtered1 = ar.filter!"a.i & 1"; auto filtered2 = ar.filter!"!(a.i & 1)"; assert(serializeToJson(filtered1) == `[{"i":1},{"i":3},{"i":17}]`); assert(serializeToJson(filtered2) == `[{"i":4}]`);
Examples:uint[2] ar = [1, 2]; assert(serializeToJson(ar) == `[1,2]`); assert(serializeToJson(ar[]) == `[1,2]`); assert(serializeToJson(ar[0 .. 0]) == `[]`); assert(serializeToJson((uint[]).init) == `null`);
- void
serializeValue
(S, T)(ref Sserializer
, auto ref T[string]value
); - String-value associative array serializationExamples:
uint[string] ar = ["a" : 1]; assert(serializeToJson(ar) == `{"a":1}`); ar.remove("a"); assert(serializeToJson(ar) == `{}`); assert(serializeToJson((uint[string]).init) == `null`);
- void
serializeValue
(S, V : const(T[K]), T, K)(ref Sserializer
, Vvalue
)
if (is(K == enum)); - Enumeration-value associative array serializationExamples:
enum E { a, b } uint[E] ar = [E.a : 1]; assert(serializeToJson(ar) == `{"a":1}`); ar.remove(E.a); assert(serializeToJson(ar) == `{}`); assert(serializeToJson((uint[string]).init) == `null`);
- void
serializeValue
(S, V : const(T[K]), T, K)(ref Sserializer
, Vvalue
)
if (isIntegral!K && !is(K == enum)); - integral typed value associative array serializationExamples:
uint[short] ar = [256 : 1]; assert(serializeToJson(ar) == `{"256":1}`); ar.remove(256); assert(serializeToJson(ar) == `{}`); assert(serializeToJson((uint[string]).init) == `null`); assert(deserialize!(uint[short])(`{"256":1}`) == cast(uint[short]) [256 : 1]);
- void
serializeValue
(S, N)(ref Sserializer
, auto ref Nvalue
)
if (isStdNullable!N && !isVariant!N); - Nullable type serializationExamples:
import std.typecons; struct Nested { float f; } struct T { string str; Nullable!Nested nested; } T t; assert(t.serializeToJson == `{"str":null,"nested":null}`); t.str = "txt"; t.nested = Nested(123); assert(t.serializeToJson == `{"str":"txt","nested":{"f":123.0}}`);
- void
serializeValue
(S, V)(ref Sserializer
, auto ref Vvalue
)
if ((!isStdNullable!V || isVariant!V) && isAggregateType!V && !is(V : BigInt) && !isInputRange!V); - Struct and class type serializationExamples:Alias this support
struct S { int u; } struct C { int b; S s; alias s this; } assert(C(4, S(3)).serializeToJson == `{"u":3,"b":4}`);
Examples:Custom serializeimport mir.conv: to; struct S { void serialize(S)(ref S serializer) const { auto state = serializer.structBegin; serializer.putEscapedKey("foo"); serializer.putValue("bar"); serializer.structEnd(state); } } enum json = `{"foo":"bar"}`; assert(serializeToJson(S()) == json); assert(serializeToAsdf(S()).to!string == json);
Examples:mir.algebraic support.import mir.algebraic: Variant, Nullable, This; alias V = Nullable!(double, string, This[], This[string]); V v; assert(v.serializeToJson == "null", v.serializeToJson); v = [V(2), V("str"), V(["key":V(1.0)])]; assert(v.serializeToJson == `[2.0,"str",{"key":1.0}]`);
Examples:mir.algebraic with manual serialization.import asdf.asdf; static struct Response { import mir.algebraic: TaggedVariant; alias Union = TaggedVariant!( ["double_", "string", "array", "table"], double, string, Response[], Response[string], ); Union data; alias Tag = Union.Kind; // propogates opEquals, opAssign, and other primitives alias data this; static foreach (T; Union.AllowedTypes) this(T v) @safe pure nothrow @nogc { data = v; } void serialize(S)(ref S serializer) const { import asdf: serializeValue; import mir.algebraic: visit; auto o = serializer.structBegin(); serializer.putKey("tag"); serializer.serializeValue(kind); serializer.putKey("data"); data.visit!( (double v) => serializer.serializeValue(v), // specialization for double if required (const Response[string] v) => serializer.serializeValue(cast(const(Response)[string])v), (v) => serializer.serializeValue(v), ); serializer.structEnd(o); } SerdeException deserializeFromAsdf(Asdf asdfData) { import asdf : deserializeValue; import std.traits : EnumMembers; Tag tag; if (auto e = asdfData["tag"].deserializeValue(tag)) return e; final switch (tag) { foreach (m; EnumMembers!Tag) { case m: { alias T = Union.AllowedTypes[m]; data = T.init; if (auto e = asdfData["data"].deserializeValue(data.trustedGet!T)) return e; break; } } } return null; } } Response v = 3.0; assert(v.kind == Response.Tag.double_); v = "str"; assert(v == "str"); import asdf; assert(v.serializeToJson == `{"tag":"string","data":"str"}`); v = Response.init; v = `{"tag":"array","data":[{"tag":"string","data":"S"}]}`.deserialize!Response; assert(v.kind == Response.Tag.array); assert(v.get!(Response[])[0] == "S");
- SerdeException
deserializeValue
(T : typeof(null))(Asdfdata
, T); - Deserialize null valueExamples:
assert(deserializeValue(serializeToAsdf(null), null) is null);
- pure @safe SerdeException
deserializeValue
(T : bool)(Asdfdata
, ref Tvalue
); - Deserialize boolean valueExamples:
assert(deserialize!bool(serializeToAsdf(true))); assert(deserialize!bool(serializeToJson(true)));
- SerdeException
deserializeValue
(V)(Asdfdata
, ref Vvalue
)
if (isNumeric!V && !is(V == enum)); - Deserialize numeric value.
Special deserialisation string values
"+NAN" "+NaN" "+nan" "-NAN" "-NaN" "-nan" "NAN" "NaN" "nan" "+INF" "+Inf" "+inf" "-INF" "-Inf" "-inf" "INF" "Inf" "inf" Examples:import std.bigint; assert(deserialize!ulong (serializeToAsdf(20)) == ulong (20)); assert(deserialize!ulong (serializeToJson(20)) == ulong (20)); assert(deserialize!double(serializeToAsdf(20)) == double(20)); assert(deserialize!double(serializeToJson(20)) == double(20)); assert(deserialize!BigInt(serializeToAsdf(20)) == BigInt(20)); assert(deserialize!BigInt(serializeToJson(20)) == BigInt(20)); assert(deserialize!float (serializeToJson ("2.40")) == float (2.40)); assert(deserialize!double(serializeToJson ("2.40")) == double(2.40)); assert(deserialize!double(serializeToAsdf("-2.40")) == double(-2.40)); import std.math : isNaN, isInfinity; assert(deserialize!float (serializeToJson ("+NaN")).isNaN); assert(deserialize!float (serializeToJson ("INF")).isInfinity); assert(deserialize!float (serializeToJson ("-inf")).isInfinity);
- SerdeException
deserializeValue
(V)(Asdfdata
, ref Vvalue
)
if (is(V == enum)); - Deserialize enum valueExamples:
@serdeIgnoreCase enum Key { foo } assert(deserialize!Key(`"FOO"`) == Key.foo); assert(deserialize!Key(serializeToAsdf("foo")) == Key.foo);
- SerdeException
deserializeScopedString
(V : const(char)[])(Asdfdata
, ref Vvalue
); - Deserializes scoped string value. This function does not allocate a new string and just make a raw cast of ASDF data.
- SerdeException
deserializeValue
(V)(Asdfdata
, ref Vvalue
)
if (is(V : const(char)[]) && !isAggregateType!V && !is(V == enum) && !isStdNullable!V); - Deserializes string value. This function allocates new string.Examples:String enums supports only enum keys
enum SimpleEnum : string { @serdeKeys("se1", "se1value") se1 = "se1value", @serdeKeys("se2", "se2value") se2 = "se2value", @serdeKeys("se3", "se3value") se3 = "se3value", } struct Simple { SimpleEnum en; SimpleEnum ex; } Simple simple = `{"en":"se2", "ex":"se3value"}`.deserialize!Simple; assert(simple.en == SimpleEnum.se2); assert(simple.ex == SimpleEnum.se3);
Examples:issue #115import asdf; import std.typecons; struct Example { @serdeOptional Nullable!string field1; } assert(`{}`.deserialize!Example == Example()); assert(Example().serializeToJson == `{"field1":null}`);
Examples:assert(deserialize!string(serializeToJson(null)) is null); assert(deserialize!string(serializeToAsdf(null)) is null); assert(deserialize!string(serializeToJson("\tbar")) == "\tbar"); assert(deserialize!string(serializeToAsdf("\"bar")) == "\"bar");
- SerdeException
deserializeValue
(V)(Asdfdata
, ref Vvalue
)
if (is(V == char) && !is(V == enum)); - Deserialize single charExamples:
assert(deserialize!char(`"a"`) == 'a'); assert(deserialize!byte(`-4`) == -4); // regression control
- SerdeException
deserializeValue
(V : T[], T)(Asdfdata
, ref Vvalue
)
if (!isSomeChar!T && !isStaticArray!V); - Deserialize arrayExamples:
assert(deserialize!(int[])(serializeToJson(null)) is null); assert(deserialize!(int[])(serializeToAsdf(null)) is null); assert(deserialize!(int[])(serializeToJson([1, 3, 4])) == [1, 3, 4]); assert(deserialize!(int[])(serializeToAsdf([1, 3, 4])) == [1, 3, 4]);
- SerdeException
deserializeValue
(V : T[N], T, size_t N)(Asdfdata
, ref Vvalue
); - Deserialize static arrayExamples:
assert(deserialize!(int[4])(serializeToJson(null)) == [0, 0, 0, 0]); assert(deserialize!(int[4])(serializeToAsdf(null)) == [0, 0, 0, 0]); assert(deserialize!(int[4])(serializeToJson([1, 3, 4])) == [1, 3, 4, 0]); assert(deserialize!(int[4])(serializeToAsdf([1, 3, 4])) == [1, 3, 4, 0]); assert(deserialize!(int[2])(serializeToJson([1, 3, 4])) == [1, 3]); assert(deserialize!(int[2])(serializeToAsdf([1, 3, 4])) == [1, 3]); assert(deserialize!(char[2])(serializeToAsdf(['a','b'])) == ['a','b']); assert(deserialize!(char[2])(serializeToAsdf(['a','\0'])) == ['a','\0']); assert(deserialize!(char[2])(serializeToAsdf(['a','\255'])) == ['a','\255']); assert(deserialize!(char[2])(serializeToAsdf(['\255'])) == ['\255','\0']); assert(deserialize!(char[2])(serializeToAsdf(['\255', '\255', '\255'])) == ['\255','\255']);
Examples:AA with value of aggregate typestruct Foo { } assert (deserialize!(Foo[int])(serializeToJson([1: Foo()])) == [1:Foo()]);
- SerdeException
deserializeValue
(V : T[string], T)(Asdfdata
, ref Vvalue
); - Deserialize string-value associative arrayExamples:
assert(deserialize!(int[string])(serializeToJson(null)) is null); assert(deserialize!(int[string])(serializeToAsdf(null)) is null); assert(deserialize!(int[string])(serializeToJson(["a" : 1, "b" : 2])) == ["a" : 1, "b" : 2]); assert(deserialize!(int[string])(serializeToAsdf(["a" : 1, "b" : 2])) == ["a" : 1, "b" : 2]);
- SerdeException
deserializeValue
(V : T[E], T, E)(Asdfdata
, ref Vvalue
)
if (is(E == enum)); - Deserialize enumeration-value associative arrayExamples:
enum E {a, b} assert(deserialize!(int[E])(serializeToJson(null)) is null); assert(deserialize!(int[E])(serializeToAsdf(null)) is null); assert(deserialize!(int[E])(serializeToJson([E.a : 1, E.b : 2])) == [E.a : 1, E.b : 2]); assert(deserialize!(int[E])(serializeToAsdf([E.a : 1, E.b : 2])) == [E.a : 1, E.b : 2]);
- SerdeException
deserializeValue
(V : T[K], T, K)(Asdfdata
, ref Vvalue
)
if (isIntegral!K && !is(K == enum)); - Deserialize associative array with integral type keyExamples:
assert(deserialize!(int[int])(serializeToJson(null)) is null); assert(deserialize!(int[int])(serializeToAsdf(null)) is null); assert(deserialize!(int[int])(serializeToJson([2 : 1, 40 : 2])) == [2 : 1, 40 : 2]); assert(deserialize!(int[int])(serializeToAsdf([2 : 1, 40 : 2])) == [2 : 1, 40 : 2]);
Examples:import std.typecons; struct Nested { float f; } struct T { string str; Nullable!Nested nested; @serdeOptional Nullable!bool nval; } T t; assert(deserialize!T(`{"str":null,"nested":null}`) == t); t.str = "txt"; t.nested = Nested(123); t.nval = false; assert(deserialize!T(`{"str":"txt","nested":{"f":123},"nval":false}`) == t);
- SerdeException
deserializeValue
(V)(Asdfdata
, ref Vvalue
)
if (isAggregateType!V); - Deserialize aggregate valueExamples: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}`);
Examples:JsonAlgebraic alias supportimport 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);
Examples:User defined algebraic types deserialization supports any subset of the following types:- typeof(null)
- bool
- long
- double
- string
- AnyType[]
- StringMap!AnyType
- AnyType[string]
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]);
Examples: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[]);
Examples:Alias this supportstruct S { int a; } struct C { S s; alias s this; int b; } assert(`{"a":3, "b":4}`.deserialize!C == C(S(3), 4));
Examples:serdeOrderedIn supprotstatic 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}}`);
Examples:serdeRealOrderedIn supprotstatic 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}}`);
Examples:struct A { string str; } struct B { A a; string serialize() const { return asdf.serializeToJson(a); } } assert(B(A("2323")).serialize == `{"str":"2323"}`);
Copyright © 2016-2022 by Ilya Yaroshenko | Page generated by
Ddoc on Thu Mar 24 03:41:37 2022