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 }