1 /**
2  * Модуль сериализатора JSON
3  *
4  * Copyright: (c) 2015-2017, Milofon Project.
5  * License: Subject to the terms of the BSD license, as written in the included LICENSE.txt file.
6  * Author: <m.galanin@milofon.org> Maksim Galanin
7  * Date: 2018-01-28
8  */
9 
10 module dango.service.serializer.json;
11 
12 private
13 {
14     import std.algorithm.searching : startsWith;
15     import std.base64 : Base64;
16 
17     import vibe.data.json;
18 
19     import dango.service.serializer.core;
20 }
21 
22 
23 class JsonSerializer : Serializer
24 {
25     override void initialize(Properties config) {}
26 
27 
28     override UniNode deserialize(ubyte[] bytes)
29     {
30         auto strData = cast(string)bytes;
31         Json json = parseJson(strData);
32         return toUniNode(json);
33     }
34 
35 
36     override ubyte[] serialize(UniNode node)
37     {
38         Json json = fromUniNode(node);
39         return cast(ubyte[])json.toString();
40     }
41 }
42 
43 
44 private:
45 
46 
47 UniNode toUniNode(Json input)
48 {
49     UniNode convert(Json node)
50     {
51         switch(node.type) with (Json)
52         {
53             case Type.undefined:
54             case Type.null_:
55                 return UniNode();
56             case Type.bool_:
57                 return UniNode(node.get!bool);
58             case Type.int_:
59             case Type.bigInt:
60                 return UniNode(node.get!long);
61             case Type.float_:
62                 return UniNode(node.get!double);
63             case Type..string:
64                 string val = node.get!string;
65                 if (val.startsWith("base64:"))
66                     return UniNode(Base64.decode(val[7..$]));
67                 else
68                     return UniNode(val);
69             case Type.array:
70             {
71                 UniNode[] arr = new UniNode[](node.length);
72                 foreach(i, Json ch; node.get!(Json[]))
73                     arr[i] = convert(ch);
74                 return UniNode(arr);
75             }
76             case Type.object:
77             {
78                 UniNode[string] map;
79                 foreach(string key, Json ch; node)
80                     map[key] = convert(ch);
81                 return UniNode(map);
82             }
83             default:
84                 return UniNode();
85         }
86     }
87 
88     return convert(input);
89 }
90 
91 
92 Json fromUniNode(UniNode input)
93 {
94     Json convert(UniNode node)
95     {
96         switch(node.type) with (UniNode)
97         {
98             case Type.nil:
99                 return Json();
100             case Type.boolean:
101                 return Json(node.get!bool);
102             case Type.signed:
103                 return Json(node.get!long);
104             case Type.unsigned:
105                 return Json(node.get!ulong);
106             case Type.floating:
107                 return Json(node.get!double);
108             case Type.raw:
109                 string result = "base64:" ~ Base64.encode(node.get!(ubyte[])).idup;
110                 return Json(result);
111             case Type.text:
112                 return Json(node.get!string);
113             case Type.array:
114             {
115                 Json arr = Json.emptyArray();
116                 foreach(UniNode ch; node.get!(UniNode[]))
117                     arr ~= convert(ch);
118                 return arr;
119             }
120             case Type.object:
121             {
122                 Json map = Json.emptyObject();
123                 foreach(string key, UniNode ch; node.get!(UniNode[string]))
124                     map[key] = convert(ch);
125                 return map;
126             }
127             default:
128                 return Json();
129         }
130     }
131 
132     return convert(input);
133 }