1 module netorcai.json_util; 2 3 import std.json, std.conv, std.format, std.algorithm, std.exception; 4 5 /// Reads a boolean from a JSONValue (handling several ways to store it) 6 bool getBool(in JSONValue v) 7 { 8 bool value; 9 10 if (v.type == JSON_TYPE.TRUE) 11 value = true; 12 else if (v.type == JSON_TYPE.FALSE) 13 value = false; 14 else if (v.type == JSON_TYPE.INTEGER) 15 { 16 enforce([0, 1].canFind(v.integer), 17 format!"Cannot deduce boolean value from integer %d"(v.integer)); 18 value = to!bool(v.integer); 19 } 20 else 21 { 22 enforce(0, "Cannot read bool value from JSONValue " ~ v.toString); 23 } 24 25 return value; 26 } 27 28 unittest 29 { 30 auto json = parseJSON(`{"a":true, 31 "b":false, 32 "c":0, 33 "d":1, 34 "e":2, 35 "f":42.51}`); 36 37 assert(json["a"].getBool == true); 38 assert(json["b"].getBool == false); 39 assert(json["c"].getBool == false); 40 assert(json["d"].getBool == true); 41 42 auto e = collectException(json["e"].getBool); 43 assert(e, "Should NOT be able to retrieve boolean value from JSON integer 2"); 44 45 e = collectException(json["f"].getBool); 46 assert(e, "Should NOT be able to retrieve boolean value from JSON double 42.51"); 47 } 48 49 /// Reads an integer from a JSONValue (handling several ways to store it) 50 int getInt(in JSONValue v) 51 { 52 int value; 53 54 if (v.type == JSON_TYPE.INTEGER) 55 value = to!int(v.integer); 56 else 57 enforce(0, "Cannot read int value from JSONValue " ~ v.toString); 58 59 return value; 60 } 61 62 unittest 63 { 64 auto json = parseJSON(`{"a":-10, 65 "b":37, 66 "c":42000, 67 "d":123456789, 68 "e":true, 69 "f":42.51}`); 70 71 assert(json["a"].getInt == -10); 72 assert(json["b"].getInt == 37); 73 assert(json["c"].getInt == 42_000); 74 assert(json["d"].getInt == 123_456_789); 75 76 auto e = collectException(json["e"].getInt); 77 assert(e, "Should NOT be able to retrieve integer value from JSON bool"); 78 79 e = collectException(json["f"].getInt); 80 assert(e, "Should NOT be able to retrieve integer value from JSON double 42.51"); 81 } 82 83 /// Reads a double from a JSONValue (handling several ways to store it) 84 double getDouble(in JSONValue v) 85 { 86 double value; 87 88 if (v.type == JSON_TYPE.FLOAT) 89 value = v.floating; 90 else if (v.type == JSON_TYPE.INTEGER) 91 value = to!double(v.integer); 92 else 93 enforce(0, "Cannot read double value from JSONValue " ~ v.toString); 94 95 return value; 96 } 97 98 unittest 99 { 100 auto json = parseJSON(`{"a":-10, 101 "b":37, 102 "c":42000, 103 "d":123456789, 104 "e":true, 105 "f":42.51}`); 106 107 assert(json["a"].getDouble == -10); 108 assert(json["b"].getDouble == 37); 109 assert(json["c"].getDouble == 42_000); 110 assert(json["d"].getDouble == 123_456_789); 111 112 immutable auto e = collectException(json["e"].getDouble); 113 assert(e, "Should NOT be able to retrieve double value from JSON bool"); 114 115 assert(json["f"].getDouble == 42.51); 116 }