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}`);
Custom serialize
import 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);
$(GMREF mir-core, 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}]`);
$(GMREF mir-core, mir, algebraic) with manual serialization.
1 import asdf.asdf; 2 3 static struct Response 4 { 5 import mir.algebraic: Variant; 6 7 static union Response_ 8 { 9 double double_; 10 immutable(char)[] string; 11 Response[] array; 12 Response[immutable(char)[]] table; 13 } 14 15 alias Union = Variant!Response_; 16 17 Union data; 18 alias Tag = Union.Kind; 19 // propogates opEquals, opAssign, and other primitives 20 alias data this; 21 22 static foreach (T; Union.AllowedTypes) 23 this(T v) @safe pure nothrow @nogc { data = v; } 24 25 void serialize(S)(ref S serializer) const 26 { 27 import asdf: serializeValue; 28 import mir.algebraic: visit; 29 30 auto o = serializer.structBegin(); 31 serializer.putKey("tag"); 32 serializer.serializeValue(kind); 33 serializer.putKey("data"); 34 data.visit!( 35 (double v) => serializer.serializeValue(v), // specialization for double if required 36 (const Response[string] v) => serializer.serializeValue(cast(const(Response)[string])v), 37 (v) => serializer.serializeValue(v), 38 ); 39 serializer.structEnd(o); 40 } 41 42 SerdeException deserializeFromAsdf(Asdf asdfData) 43 { 44 import asdf : deserializeValue; 45 import std.traits : EnumMembers; 46 47 Tag tag; 48 if (auto e = asdfData["tag"].deserializeValue(tag)) 49 return e; 50 final switch (tag) 51 { 52 foreach (m; EnumMembers!Tag) 53 { 54 case m: { 55 alias T = Union.AllowedTypes[m]; 56 data = T.init; 57 if (auto e = asdfData["data"].deserializeValue(data.trustedGet!T)) 58 return e; 59 break; 60 } 61 } 62 } 63 return null; 64 } 65 } 66 67 Response v = 3.0; 68 assert(v.kind == Response.Tag.double_); 69 v = "str"; 70 assert(v == "str"); 71 72 import asdf; 73 assert(v.serializeToJson == `{"tag":"string","data":"str"}`); 74 v = Response.init; 75 v = `{"tag":"array","data":[{"tag":"string","data":"S"}]}`.deserialize!Response; 76 assert(v.kind == Response.Tag.array); 77 assert(v.get!(Response[])[0] == "S");
Struct and class type serialization