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
Examples:
import std.bigint; import std.datetime; import std.conv; enum E { a, b, c, } static class C { private double _foo; pure: this() { _foo = 4; } double foo() @property { return _foo + 10; } void foo(double d) @property { _foo = d - 10; } } static struct DateTimeProxy { DateTime datetime; alias datetime this; static DateTimeProxy deserialize(Asdf data) pure { string val; deserializeScopedString(data, val); return DateTimeProxy(DateTime.fromISOString(val)); } void serialize(S)(ref S serializer) pure { serializer.putValue(datetime.toISOString); } } static struct S { @serializedAs!DateTimeProxy DateTime time; C object; string[E] map; @serializationKeys("bar_common", "bar") string bar; } enum json = `{"time":"20160304T000000","object":{"foo":14},"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(value) == json); assert(serializeToAsdf(value).to!string == json); assert(deserialize!S(json).serializeToJson == json);
Examples:
finalizeSerialization method
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
static struct S { string a; int b; @serializationIgnoreIn 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; } } assert(`{"a":"bar","b":3,"c":{"d":{"e":6,"g":7}}}`.deserialize!S == S("bar", 3, 13));
Examples:
A user may define setter and/or getter properties.
static struct S { @serializationIgnore 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)
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; } } static assert(isNullable!MyNullable); 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; import std.stdio; 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; } } static assert(isNullable!(Nullable!(int))); 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"));
Examples:
Support for floating point nan and (partial) infinity
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));
JSON serialization function.
Examples:
struct S { string foo; uint bar; } assert(serializeToJson(S("str", 4)) == `{"foo":"str","bar":4}`);
JSON serialization function with pretty formatting.
Examples:
static struct S { int a; } assert(S(4).serializeToJsonPretty == "{\n\t\"a\": 4\n}");
ASDF serialization function
Examples:
struct S { string foo; uint bar; } assert(serializeToAsdf(S("str", 4)).to!string == `{"foo":"str","bar":4}`);
Deserialization function
Examples:
struct S { string foo; uint bar; } assert(deserialize!S(`{"foo":"str","bar":4}`) == S("str", 4));
Serialization proxy for structs, classes, and enums.
Example Proxy for types.
@serializedAs!ProxyE enum E { none, bar, } // const(char)[] doesn't reallocate ASDF data. @serializedAs!(const(char)[]) struct ProxyE { E e; this(E e) { this.e = e; } this(in char[] str) { switch(str) { case "NONE": case "NA": case "N/A": e = E.none; break; case "BAR": case "BR": e = E.bar; break; default: throw new Exception("Unknown: " ~ cast(string)str); } } string toString() { if (e == E.none) return "NONE"; else return "BAR"; } E opCast(T : E)() { return e; } } unittest { assert(serializeToJson(E.bar) == `"BAR"`); assert(`"N/A"`.deserialize!E == E.none); assert(`"NA"`.deserialize!E == E.none); }
Examples:
Proxy for members
struct S { // const(char)[] doesn't reallocate ASDF data. @serializedAs!(const(char)[]) uint bar; } auto json = `{"bar":"4"}`; assert(serializeToJson(S(4)) == json); assert(deserialize!S(json) == S(4));
Main serialization attribute type
string list
Additional serialization attribute type
2D string list
Attribute for key overloading during Serialization and Deserialization.
The first argument overloads the key value during serialization unless serializationKeyOut is given.
Examples:
static struct S { @serializationKeys("b", "a") string s; } assert(`{"a":"d"}`.deserialize!S.serializeToJson == `{"b":"d"}`);
Attribute for key overloading during deserialization.
Examples:
static struct S { @serializationKeysIn("a") string s; } assert(`{"a":"d"}`.deserialize!S.serializeToJson == `{"s":"d"}`);
Attribute that force deserialiser to throw an exception that the field was not found in the input.
Examples:
import std.exception; struct S { @serializationRequired string field; } assert(`{"field":"val"}`.deserialize!S.field == "val"); assertThrown(`{"other":"val"}`.deserialize!S);
Attribute for key overloading during deserialization.
AttentionserializationMultiKeysIn is not optimized yet and may significantly slowdown deserialization.
Examples:
static struct S { @serializationMultiKeysIn(["a", "b", "c"]) string s; } assert(`{"a":{"b":{"c":"d"}}}`.deserialize!S.s == "d");
Attribute for key overloading during serialization.
Examples:
static struct S { @serializationKeyOut("a") string s; } assert(`{"s":"d"}`.deserialize!S.serializeToJson == `{"a":"d"}`);
Attribute to ignore fields.
Examples:
static struct S { @serializationIgnore string s; } assert(`{"s":"d"}`.deserialize!S.s == null); assert(S("d").serializeToJson == `{}`);
Attribute to ignore field during deserialization.
Examples:
static struct S { @serializationIgnoreIn string s; } assert(`{"s":"d"}`.deserialize!S.s == null); assert(S("d").serializeToJson == `{"s":"d"}`);
Attribute to ignore field during serialization.
Examples:
static struct S { @serializationIgnoreOut string s; } assert(`{"s":"d"}`.deserialize!S.s == "d"); assert(S("d").serializeToJson == `{}`);
Can be applied only to strings fields.
Does not allocate new data when deserializeing. Raw ASDF data is used for strings instead of new memory allocation.
Use this attributes only for strings that would not be used after ASDF deallocation.
Examples:
import std.uuid; static struct S { @serializationScoped @serializedAs!string UUID id; } assert(`{"id":"8AB3060E-2cba-4f23-b74c-b52db3bdfb46"}`.deserialize!S.id == UUID("8AB3060E-2cba-4f23-b74c-b52db3bdfb46"));
Allows to use flexible deserialization rules the same way like Asdf.opCast does.
See Also:
.
Examples:
import std.uuid; static struct S { @serializationFlexible uint a; } assert(`{"a":"100"}`.deserialize!S.a == 100); assert(`{"a":true}`.deserialize!S.a == 1); assert(`{"a":null}`.deserialize!S.a == 0);
Examples:
static struct Vector { @serializationFlexible int x; @serializationFlexible int y; } auto json = `[{"x":"1","y":2},{"x":null, "y": null},{"x":1, "y":2}]`; auto decoded = json.deserialize!(Vector[]); import std.conv; assert(decoded == [Vector(1, 2), Vector(0, 0), Vector(1, 2)], decoded.text);
Allows serialize / deserialize fields like arrays.
A range or a container should be iterable for serialization.
Following code should compile:
foreach(ref value; yourRangeOrContainer) { ... }put(value) method is used for deserialization.
See Also:
Examples:
import std.range; import std.uuid; static struct S { private int count; @serializationLikeArray auto numbers() @property // uses `foreach` { return iota(count); } @serializationLikeArray @serializedAs!string // input element type of @serializationIgnoreOut Appender!(string[]) strings; //`put` method is used } assert(S(5).serializeToJson == `{"numbers":[0,1,2,3,4]}`); assert(`{"strings":["a","b"]}`.deserialize!S.strings.data == ["a","b"]);
Allows serialize / deserialize fields like objects.
Object should have opApply method to allow serialization.
Following code should compile:
foreach(key, value; yourObject)
{
...
}
Object should have only one opApply method with 2 argument to allow automatic value type deduction.
opIndexAssign or opIndex is used for deserialization to support required syntax:
yourObject["key"] = value;
Multiple value types is supported for deserialization.
See Also:
Examples:
static struct M { private int sum; // opApply is used for serialization int opApply(int delegate(in char[] key, int val) pure dg) pure { if(auto r = dg("a", 1)) return r; if(auto r = dg("b", 2)) return r; if(auto r = dg("c", 3)) return r; return 0; } // opIndexAssign for deserialization void opIndexAssign(int val, string key) pure { sum += val; } } static struct S { @serializationLikeObject @serializedAs!int M obj; } assert(S.init.serializeToJson == `{"obj":{"a":1,"b":2,"c":3}}`); assert(`{"obj":{"a":1,"b":2,"c":9}}`.deserialize!S.obj.sum == 12);
Attributes for in and out transformations.
Return type of in transformation must be implicitly convertable to the type of the field.
Return type of out transformation may be differ from the type of the field.
In transformation would be applied after serialization proxy if any.
Out transformation would be applied before serialization proxy if any.
Examples:
// global unary function static int fin(int i) { return i + 2; } static struct S { @serializationTransformIn!fin @serializationTransformOut!`"str".repeat.take(a).joiner("_").to!string` int a; } auto s = deserialize!S(`{"a":3}`); assert(s.a == 5); assert(serializeToJson(s) == `{"a":"str_str_str_str_str"}`);
JSON serialization back-end
JSON string buffer
uint objectBegin();
void objectEnd(uint state);
uint arrayBegin();
void arrayEnd(uint state);
void putEscapedKey(in char[] key);
void putKey(in char[] key);
void putNumberValue(Num)(Num num, FormatSpec!char fmt = FormatSpec!char.init);
void putValue(typeof(null));
void putValue(bool b);
void putValue(in char[] str);
void putValue(Num)(Num num)
if (isNumeric!Num && !is(Num == enum));
void elemBegin();
void flush();
void objectEnd(uint state);
uint arrayBegin();
void arrayEnd(uint state);
void putEscapedKey(in char[] key);
void putKey(in char[] key);
void putNumberValue(Num)(Num num, FormatSpec!char fmt = FormatSpec!char.init);
void putValue(typeof(null));
void putValue(bool b);
void putValue(in char[] str);
void putValue(Num)(Num num)
if (isNumeric!Num && !is(Num == enum));
void elemBegin();
void flush();
Serialization primitives
Creates JSON serialization back-end.
Use sep equal to "\t" or " " for pretty formatting.
Examples:
import std.array; import std.bigint; auto app = appender!string; auto ser = jsonSerializer(&app.put!(const(char)[])); auto state0 = ser.objectBegin; ser.putEscapedKey("null"); ser.putValue(null); ser.putEscapedKey("array"); auto state1 = ser.arrayBegin(); 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.arrayEnd(state1); ser.objectEnd(state0); ser.flush; assert(app.data == `{"null":null,"array":[null,123,1.2300000123e+07,"\t","\r","\n",1234567890]}`);
ASDF serialization back-end
Output buffer
pure size_t objectBegin();
pure void objectEnd(size_t state);
pure size_t arrayBegin();
pure void arrayEnd(size_t state);
alias putEscapedKey = putKey;
pure void putKey(in char[] key);
pure void putNumberValue(Num)(Num num, FormatSpec!char fmt = FormatSpec!char.init);
pure void putValue(typeof(null));
pure void putValue(bool b);
pure void putValue(in char[] str);
void putValue(Num)(Num num)
if (isNumeric!Num && !is(Num == enum));
static pure void elemBegin();
static pure void flush();
pure void objectEnd(size_t state);
pure size_t arrayBegin();
pure void arrayEnd(size_t state);
alias putEscapedKey = putKey;
pure void putKey(in char[] key);
pure void putNumberValue(Num)(Num num, FormatSpec!char fmt = FormatSpec!char.init);
pure void putValue(typeof(null));
pure void putValue(bool b);
pure void putValue(in char[] str);
void putValue(Num)(Num num)
if (isNumeric!Num && !is(Num == enum));
static pure void elemBegin();
static pure void flush();
Serialization primitives
Create ASDF serialization back-end
Examples:
import std.bigint; auto ser = asdfSerializer(); auto state0 = ser.objectBegin; ser.putEscapedKey("null"); ser.putValue(null); ser.putKey("array"); auto state1 = ser.arrayBegin(); 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.arrayEnd(state1); ser.objectEnd(state0); assert(ser.app.result.to!string == `{"null":null,"array":[null,123,1.2300000123e+07,"\t","\r","\n",1234567890]}`);
null value serialization
Examples:
assert(serializeToJson(null) == `null`);
Number serialization
Examples:
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"`);
Boolean serialization
Examples:
assert(serializeToJson(true) == `true`);
Enum serialization
Examples:
enum Key { foo } assert(serializeToJson(Key.foo) == `"foo"`);
String serialization
Examples:
assert(serializeToJson("\t \" \\") == `"\t \" \\"`);
Array serialization
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`);
String-value associative array serialization
Examples:
uint[string] ar = ["a" : 1]; assert(serializeToJson(ar) == `{"a":1}`); ar.remove("a"); assert(serializeToJson(ar) == `{}`); assert(serializeToJson((uint[string]).init) == `null`);
Enumeration-value associative array serialization
Examples:
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`);
integral typed value associative array serialization
Examples:
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]);
Nullable type serialization
Struct and class type serialization
Deserialize null value
Examples:
deserializeValue(serializeToAsdf(null), null);
Deserialize boolean value
Examples:
assert(deserialize!bool(serializeToAsdf(true))); assert(deserialize!bool(serializeToJson(true)));
Deserialize numeric value
Examples:
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);
Deserialize enum value
Examples:
enum Key { foo } assert(deserialize!Key(`"foo"`) == Key.foo); assert(deserialize!Key(serializeToAsdf("foo")) == Key.foo);
Deserializes scoped string value.
This function does not allocate a new string and just make a raw cast of ASDF data.
Deserializes string value.
This function allocates new string.
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");
Deserialize array
Examples:
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]);
Deserialize static array
Examples:
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]);
Deserialize string-value associative array
Examples:
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]);
Deserialize enumeration-value associative array
Examples:
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]);
Deserialize associative array with integral type key
Examples:
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]);
Deserialize Nullable value
Deserialize aggregate value
Copyright © 1999-2018 by the D Language Foundation | Page generated by
Ddoc on Sat Apr 7 16:50:38 2018