1 /*
2  * Hunt - A high-level D Programming Language Web framework that encourages rapid development and clean, pragmatic design.
3  *
4  * Copyright (C) 2015-2019, HuntLabs
5  *
6  * Website: https://www.huntlabs.net/
7  *
8  * Licensed under the Apache-2.0 License.
9  *
10  */
11 
12 module hunt.framework.util.uninode.Serialization;
13 
14 import std.stdio;
15 
16 private
17 {
18     import std.traits;
19     import std.json;
20     import hunt.framework.util.uninode.Core;
21     import hunt.serialization.JsonSerializer;
22 }
23 
24 /**
25  * Serialize object to UniNode
26  *
27  * Params:
28  * object = serialized object
29  */
30 UniNode serializeToUniNode(T)(T object)
31 {
32     return _serializeToUniNode!T(object);
33 }
34 
35 /**
36  * Deserialize object form UniNode
37  *
38  * Params:
39  * src = UniNode value
40  */
41 T deserializeUniNode(T)(UniNode src)
42 {
43     return _deserializeUniNode!T(src);
44 }
45 
46 /**
47  * Serialize object to UniNode
48  *
49  * Params:
50  * object = serialized object
51  */
52 UniNode jsonToUniNode(JSONValue object)
53 {
54     return _jsonToUniNode(object);
55 }
56 
57 /**
58  * Deserialize object form UniNode
59  *
60  * Params:
61  * src = UniNode value
62  */
63 JSONValue uniNodeToJSON(UniNode src)
64 {
65     return _uniNodeToJSON(src);
66 }
67 
68 
69 private
70 {
71     /**
72     * Serialize object to UniNode
73     *
74     * Params:
75     * object = serialized object
76     */
77     UniNode _serializeToUniNode(T)(T object)
78     {
79         static if (is(T == UniNode))
80         {
81             return object;
82         }
83         else static if (isUniNodeType!(T, UniNode))
84         {
85             static if (isUniNodeInnerType!T)
86             {
87                 return UniNode(object);
88             }
89             else static if (isUniNodeArray!(T, UniNode))
90             {
91                 return UniNode(object);
92             }
93             else static if (isUniNodeObject!(T, UniNode))
94             {
95                 return UniNode(object);
96             }
97         }
98         else static if (is(T == struct) || is(T == class))
99         {
100             return _jsonToUniNode(toJson(object));
101         }
102         else static if (isStaticArray!T)
103         {
104             UniNode[object.length] nodes;
105             foreach (node; object)
106             {
107                 nodes ~= _serializeToUniNode(node);
108             }
109 
110             return UniNode(nodes);
111         }
112         else static if (isDynamicArray!T)
113         {
114             UniNode[] nodes;
115             foreach (node; object)
116             {
117                 nodes ~= _serializeToUniNode(node);
118             }
119 
120             return UniNode(nodes);
121         }
122     }
123 
124     /**
125     * Convert JSONValue to UniNode
126     *
127     * Params:
128     * data = JSONValue
129     */
130     UniNode _jsonToUniNode(JSONValue data)
131     {
132         if (data.type == JSONType.integer)
133         {
134             return UniNode(data.integer);
135         }
136         else if (data.type == JSONType.null_)
137         {
138             return UniNode((null));
139         }
140         else if (data.type == JSONType..string)
141         {
142             return UniNode(data.str);
143         }
144         else if (data.type == JSONType.false_)
145         {
146             return UniNode(false);
147         }
148         else if (data.type == JSONType.true_)
149         {
150             return UniNode(true);
151         }
152         else if (data.type == JSONType.float_)
153         {
154             return UniNode(data.floating);
155         }
156         else if (data.type == JSONType.uinteger)
157         {
158             return UniNode(data.uinteger);
159         }
160         else if (data.type == JSONType.array)
161         {
162             UniNode[] nodes;
163             foreach (value; data.array)
164             {
165                 nodes ~= _jsonToUniNode(value);
166             }
167             return UniNode(nodes);
168         }
169         else if (data.type == JSONType.object)
170         {
171             UniNode[string] node;
172             foreach (k, v; data.object)
173             {
174                 node[k] = _jsonToUniNode(v);
175             }
176             return UniNode(node);
177         }
178         return UniNode(null);
179     }
180     /**
181     * Deserialize object form UniNode
182     *
183     * Params:
184     * src = UniNode value
185     */
186     T _deserializeUniNode(T)(UniNode src)
187     {
188         static if (is(T == UniNode))
189         {
190             return src;
191         }
192         else static if (isUniNodeType!(T, UniNode))
193         {
194             return src.get!T();
195         }
196         else static if (is(T == struct) || is(T == class))
197         {
198             return toObject!T(_uniNodeToJSON(src));
199         }
200         else
201         {
202             return unserialize!(T)(cast(byte[])(src.get!(ubyte[])));
203         }
204     }
205     /**
206     * Convert UniNode to JSONValue
207     *
208     * Params:
209     * data = UniNode
210     */
211     JSONValue _uniNodeToJSON(UniNode node)
212     {
213         JSONValue data;
214         if (node.kind == UniNode.Kind.nil)
215         {
216             return data;
217         }
218         else if (node.kind == UniNode.Kind.boolean)
219         {
220             data = node.get!bool();
221         }
222         else if (node.kind == UniNode.Kind.uinteger)
223         {
224             data = node.get!ulong();
225         }
226         else if (node.kind == UniNode.Kind.integer)
227         {
228             data = node.get!long();
229         }
230         else if (node.kind == UniNode.Kind.floating)
231         {
232             data = node.get!real();
233         }
234         else if (node.kind == UniNode.Kind.text)
235         {
236             data = node.get!string();
237         }
238         else if (node.kind == UniNode.Kind.raw)
239         {
240             data = node.get!(ubyte[])();
241         }
242         else if (node.kind == UniNode.Kind.array)
243         {
244             JSONValue[] values;
245             foreach (value; node)
246             {
247                 values ~= _uniNodeToJSON(value);
248             }
249             data = values;
250         }
251         else if (node.kind == UniNode.Kind.object)
252         {
253             foreach (string k, UniNode v; node)
254             {
255                 data[k] = _uniNodeToJSON(v);
256             }
257         }
258         return data;
259     }
260 }