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 }