1 module buffer.rpc.client;
2 
3 import std.traits;
4 import std.conv : to;
5 import std.variant;
6 
7 import buffer.message;
8 
9 alias TcpRequestHandler = ubyte[]delegate(ubyte[] data);
10 
11 class Client
12 {
13     static TcpRequestHandler handler = null;
14 
15     static void bindTcpRequestHandler(TcpRequestHandler handler)
16     {
17         Client.handler = handler;
18     }
19 
20     static T call(T, Params...)(string method, Params params) if (
21             is(T == byte) || is(T == ubyte) || is(T == short) || is(T == ushort) || is(T == int)  || is(T == uint)
22          || is(T == long) || is(T == ulong) || is(T == float) || is(T == double) || is(T == bool) || is(T == char)
23          || is(T == string) || (BaseTypeTuple!T.length > 0 && is(BaseTypeTuple!T[0] == Message)))
24     {
25         assert(handler != null, "TcpRequestHandler must be bound.");
26         assert(method.length > 0, "Paramter method must be set.");
27 
28         ubyte[] response = handler(Message.serialize_without_msginfo(method, params));
29         ushort messageId;
30         TypeInfo_Class messageName;
31         string res_method;
32         Variant[] res_params = Message.deserialize(response, messageId, messageName, res_method);
33         
34         //assert(method == res_method);
35 
36         static if (isBuiltinType!T)
37         {
38             assert(res_params.length == 1, "The number of response parameters from the server is incorrect.");
39 
40             return res_params[0].get!T;
41         }
42         else
43         {
44             alias FieldTypes = FieldTypeTuple!T;
45             static assert(FieldTypes.length == params.length, "Incorrect number of parameters, " ~ T.stringof ~ " requires " ~ FieldTypes.length.to!string ~ " parameters.");
46 
47             T message = new T();
48 
49             foreach (i, type; FieldTypes)
50             {
51                 mixin(`
52                     message.` ~ FieldNameTuple!T[i] ~ ` = res_params[` ~ i.to!string ~ `].get!` ~ type.stringof ~ `;
53                 `);
54             }
55 
56             return message;
57         }
58     }
59 }