module vest.json.utils; import std.json : JSONValue, JSONException, JSONType; import std.conv : to; // Cast to any numeric double numeric()(auto ref const(JSONValue) v) { switch(v.type) { case JSONType.float_ : return v.floating; case JSONType.integer : return v.integer; case JSONType.uinteger : return v.uinteger; default: throw new JSONException("JSONValue is a " ~ to!string(v.type) ~ ", not a numeric."); } } // Check if property exists and is not null const(JSONValue)* checkNull()(auto ref const(JSONValue) v, string field) pure @safe { const(JSONValue)* ptr = field in v; return (ptr && ptr.type != JSONType.null_) ? ptr : null; } // cd source // rdmd -unittest -main vest/json/utils unittest { //import std.stdio : writeln; import std.algorithm : map; import std.json : parseJSON; import std.math : approxEqual; assert([-1, 1, 0.5, -0.5].approxEqual(parseJSON(`[-1,1,0.5,-0.5]`).array.map!(x => x.numeric))); assert(parseJSON(`0.5`).numeric.approxEqual(0.5)); assert(parseJSON(size_t.max.to!string).numeric == size_t.max); assert(null != parseJSON(`{"a":5,"b":null}`).checkNull("a")); assert(null == parseJSON(`{"a":5,"b":null}`).checkNull("b")); assert(null == parseJSON(`{"a":5,"b":null}`).checkNull("c")); assert( (*parseJSON(`{"a":5,"b":null}`).checkNull("a")).integer == 5); }