1 /// 2 module dpq.serialisers.scalar; 3 4 import std.traits; 5 import std.bitmanip; 6 import std.typecons; 7 import std.string : format; 8 9 import dpq.serialisation; 10 import dpq.value : Type; 11 import dpq.connection : Connection; 12 13 import libpq.libpq; 14 15 struct ScalarSerialiser 16 { 17 static bool isSupportedType(T)() 18 { 19 return (T.stringof in _supportedTypes) != null; 20 } 21 22 static void enforceSupportedType(T)() 23 { 24 assert( 25 isSupportedType!T, 26 "'%s' is not supported by ScalarSerialiser".format(T.stringof)); 27 } 28 29 static Nullable!(ubyte[]) serialise(T)(T val) 30 { 31 enforceSupportedType!T; 32 33 alias RT = Nullable!(ubyte[]); 34 import std.stdio; 35 36 if (isAnyNull(val)) 37 return RT.init; 38 39 return RT(nativeToBigEndian(val).dup); 40 } 41 42 static T deserialise(T)(const(ubyte)[] bytes) 43 { 44 enforceSupportedType!T; 45 46 return bytes.read!T; 47 } 48 49 static Oid oidForType(T)() 50 { 51 enforceSupportedType!T; 52 53 return _supportedTypes[T.stringof].oid; 54 } 55 56 static string nameForType(T)() 57 { 58 enforceSupportedType!T; 59 60 return _supportedTypes[T.stringof].name; 61 } 62 63 static void ensureExistence(T)(Connection c) 64 { 65 return; 66 } 67 68 private struct _Type 69 { 70 Oid oid; 71 string name; 72 } 73 74 private static enum _Type[string] _supportedTypes = [ 75 "bool": _Type(Type.BOOL, "BOOL"), 76 77 "byte": _Type(Type.CHAR, "CHAR"), 78 "char": _Type(Type.CHAR, "CHAR"), 79 80 "short": _Type(Type.INT2, "INT2"), 81 "wchar": _Type(Type.INT2, "INT2"), 82 83 "int": _Type(Type.INT4, "INT4"), 84 "dchar": _Type(Type.INT4, "INT4"), 85 86 "long": _Type(Type.INT8, "INT8"), 87 88 "float": _Type(Type.FLOAT4, "FLOAT4"), 89 "double": _Type(Type.FLOAT8, "FLOAT8") 90 ]; 91 } 92 93 unittest 94 { 95 import std.stdio; 96 97 writeln(" * ScalarSerialiser"); 98 99 // Not much to test here, since it's just a wrapper around D's stdlib 100 101 int a = 123; 102 auto serialised = ScalarSerialiser.serialise(a); 103 assert(ScalarSerialiser.deserialise!int(serialised) == a); 104 }