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 		static 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 		auto bytes = nativeToBigEndian(val);
40 		return RT(bytes.dup);
41 	}
42 
43 	static T deserialise(T)(const(ubyte)[] bytes)
44 	{
45 		enforceSupportedType!T;
46 
47 		return bytes.read!T;
48 	}
49 
50 	static Oid oidForType(T)()
51 	{
52 		enforceSupportedType!T;
53 
54 		return _supportedTypes[T.stringof].oid;
55 	}
56 
57 	static string nameForType(T)()
58 	{
59 		enforceSupportedType!T;
60 
61 		return _supportedTypes[T.stringof].name;
62 	}
63 
64 	static void ensureExistence(T)(Connection c)
65 	{
66 		return;
67 	}
68 
69 	private struct _Type
70 	{
71 		Oid oid;
72 		string name;
73 	}
74 
75 	private static enum _Type[string] _supportedTypes = [
76 		"bool":   _Type(Type.BOOL,   "BOOL"),
77 
78 		"byte":   _Type(Type.CHAR,   "CHAR"),
79 		"char":   _Type(Type.CHAR,   "CHAR"),
80 
81 		"short":  _Type(Type.INT2,   "INT2"),
82 		"wchar":  _Type(Type.INT2,   "INT2"),
83 
84 		"int":    _Type(Type.INT4,   "INT4"),
85 		"dchar":  _Type(Type.INT4,   "INT4"),
86 
87 		"long":   _Type(Type.INT8,   "INT8"),
88 
89 		"float":  _Type(Type.FLOAT4, "FLOAT4"),
90 		"double": _Type(Type.FLOAT8,   "FLOAT8")
91 	];
92 }
93 
94 unittest
95 {
96 	import std.stdio;
97 
98 	writeln(" * ScalarSerialiser");
99 
100 	// Not much to test here, since it's just a wrapper around D's stdlib
101 
102 	int a = 123;
103 	auto serialised = ScalarSerialiser.serialise(a);
104 	assert(ScalarSerialiser.deserialise!int(serialised.get) == a);
105 }