1 module xmlrpcc.data; 2 3 import std.variant : Variant; 4 import std.algorithm : reduce; 5 import std.conv : to; 6 import std.string : format; 7 8 import xmlrpcc.error; 9 10 alias XmlRpcArray = Variant[]; 11 alias XmlRpcStruct = Variant[string]; 12 13 @trusted: 14 15 struct MethodCallData { 16 string name; 17 Variant[] params; 18 19 string toString() { 20 return name ~ "(" ~ prettyParams(params) ~ ")"; 21 } 22 } 23 24 struct MethodResponseData { 25 bool fault; 26 Variant[] params; 27 28 string toString() { 29 return (fault ? "FAULT" : "OK") ~ ": " ~ prettyParams(params); 30 } 31 } 32 33 package string prettyParams(Variant[] params) { 34 return reduce!((a, b) { return a ~ (a.length ? ", " : "") ~ prettyParam(b); })("", params); 35 } 36 37 private string prettyParam(Variant param) { 38 if (param.convertsTo!string() || param.convertsTo!wstring() || param.convertsTo!dstring()) 39 return "`" ~ to!string(param) ~ "`"; 40 41 if (param.convertsTo!(const(ubyte[]))) 42 return reduce!((a, b) { return format("%s %02x", a, b); })("hex:", param.get!(const(ubyte[]))()); 43 44 if (param.convertsTo!XmlRpcArray) 45 return "[" ~ prettyParams(param.get!XmlRpcArray) ~ "]"; 46 47 if (param.convertsTo!XmlRpcStruct) { 48 string output; 49 foreach (key, value; param.get!XmlRpcStruct) { 50 output ~= output ? ", " : "["; 51 output ~= "\"" ~ key ~ "\": " ~ prettyParam(value); 52 } 53 return output ~ "]"; 54 } 55 56 return to!string(param); 57 } 58 59 version (xmlrpc_unittest) unittest { 60 import std.stdio; 61 import std.exception; 62 63 auto call = MethodCallData("method", [Variant(123), Variant(["key" : Variant(cast(ubyte[]) x"dead")]), 64 Variant(cast(const ubyte[]) x"cafe")]); 65 //writeln(call.toString()); 66 assert(call.toString() == `method(123, ["key": hex: de ad], hex: ca fe)`); 67 }