1 module sbin.repr; 2 3 import std.traits : Unqual; 4 5 import sbin.serialize; 6 import sbin.deserialize; 7 8 struct EmptyReprHandler { enum sbinReprHandler; } 9 10 template isReprHandler(RH) 11 { 12 enum isReprHandler = is(RH == struct) && __traits(hasMember, RH, "sbinReprHandler"); 13 } 14 15 unittest 16 { 17 static struct Foo { } 18 19 static assert(isReprHandler!EmptyReprHandler); 20 static assert(!isReprHandler!Foo); 21 } 22 23 template hasRepr(RH, T) if (isReprHandler!RH) 24 { 25 static if (hasSerializeRepr!(RH, T)) 26 enum hasRepr = hasDeserializeRepr!(RH, T, serializeRepr!(RH, T)); 27 else 28 enum hasRepr = false; 29 } 30 31 template hasSerializeRepr(RH, T) 32 { enum hasSerializeRepr = is(typeof(sbinSerialize!RH(RH.repr(T.init)))); } 33 34 template hasDeserializeRepr(RH, T, Repr) 35 { enum hasDeserializeRepr = is(typeof(RH.fromRepr((ubyte[]).init.sbinDeserialize!(RH, Repr)())) == Unqual!T); } 36 37 template serializeRepr(RH, T) if (hasSerializeRepr!(RH, T)) 38 { alias serializeRepr = typeof(RH.repr(T.init)); } 39 40 unittest 41 { 42 static class Foo {} 43 static struct Bar {} 44 static assert (!hasRepr!(EmptyReprHandler, int)); 45 static assert (!hasRepr!(EmptyReprHandler, Foo)); 46 static assert (!hasRepr!(EmptyReprHandler, Bar)); 47 } 48 49 unittest 50 { 51 import std.datetime : SysTime; 52 53 static struct CRH 54 { 55 enum sbinReprHandler; 56 57 static: 58 59 long repr()(auto ref const SysTime st) { return st.stdTime; } 60 SysTime fromRepr()(auto ref const long v) { return SysTime(v); } 61 } 62 63 static assert (isReprHandler!CRH); 64 static assert (!hasRepr!(EmptyReprHandler, SysTime)); 65 static assert (hasSerializeRepr!(CRH, SysTime)); 66 static assert (is(serializeRepr!(CRH, SysTime) == long)); 67 static assert (hasDeserializeRepr!(CRH, SysTime, long)); 68 static assert (hasRepr!(CRH, SysTime)); 69 }