1 /** 2 JSON Writer 3 4 Copyright: 5 Copyright © 2020-2026, Inochi2D Project 6 7 License: 8 $(LINK2 https://github.com/Inochi2D/inochi2d/blob/main/LICENSE, BSD 2-clause License) 9 10 Authors: 11 Luna Nielsen 12 */ 13 module inp.format.json.writer; 14 import inp.format.node; 15 import nulib.io.stream; 16 import nulib.io.stream.rw; 17 import nulib.math; 18 import numem; 19 20 @nogc: 21 22 /** 23 Writes $(D DataNode) to stream as JSON. 24 25 Params: 26 stream = The stream to write to 27 node = The node to write. 28 */ 29 void writeJson(Stream stream, ref DataNode node) { 30 scope StreamWriter writer = new StreamWriter(stream); 31 writer.writeJsonImpl(node); 32 } 33 34 35 36 37 // 38 // IMPLEMENTATION DETAILS 39 // 40 private: 41 42 void writeJsonString(StreamWriter writer, string text) { 43 writer.writeLE('"'); 44 foreach(char c; text) { 45 if (c == '"') { 46 writer.writeLE('\\'); 47 writer.writeLE('"'); 48 continue; 49 } 50 51 writer.writeLE!ubyte(c); 52 } 53 writer.writeLE('"'); 54 } 55 56 void writeJsonImpl()(StreamWriter writer, auto ref DataNode node) { 57 import nulib.conv : to; 58 final switch(node.type) { 59 case DataNodeType.undefined: 60 return; 61 62 case DataNodeType.blob_: 63 return; 64 65 case DataNodeType.boolean_: 66 writer.writeUTF8(node.tryCoerce!bool ? "true" : "false"); 67 return; 68 69 case DataNodeType.int_: 70 auto v = to!string(node.tryCoerce!int); 71 writer.writeUTF8(v[]); 72 return; 73 74 case DataNodeType.uint_: 75 auto v = to!string(node.tryCoerce!uint); 76 writer.writeUTF8(v[]); 77 return; 78 79 case DataNodeType.float_: 80 auto v = to!string(node.tryCoerce!float); 81 writer.writeUTF8(v[]); 82 return; 83 84 case DataNodeType.string_: 85 writer.writeJsonString(node.text); 86 return; 87 88 case DataNodeType.array_: 89 writer.writeLE('['); 90 foreach(i, ref n; node.array) { 91 writer.writeJsonImpl(n); 92 if (i+1 < node.length) 93 writer.writeLE(','); 94 } 95 writer.writeLE(']'); 96 return; 97 98 case DataNodeType.object_: 99 writer.writeLE('{'); 100 foreach(i, key, ref value; node.object) { 101 102 writer.writeJsonString(key); 103 writer.writeLE(':'); 104 writer.writeJsonImpl(value); 105 106 if (i+1 < node.length) 107 writer.writeLE(','); 108 } 109 writer.writeLE('}'); 110 return; 111 } 112 }