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