Skip to content

Commit

Permalink
Add Json.toJSONValue & Json.fromJSONValue
Browse files Browse the repository at this point in the history
  • Loading branch information
WebFreak001 committed Aug 28, 2017
1 parent 35fd705 commit 4f6ba1d
Showing 1 changed file with 92 additions and 2 deletions.
94 changes: 92 additions & 2 deletions data/vibe/data/json.d
Original file line number Diff line number Diff line change
Expand Up @@ -71,15 +71,16 @@ public import vibe.data.serialization;
public import std.json : JSONException;
import std.algorithm;
import std.array;
import std.bigint;
import std.conv;
import std.datetime;
import std.exception;
import std.format;
import std.string;
import std.json : JSONValue, JSON_TYPE;
import std.range;
import std.string;
import std.traits;
import std.typecons : Tuple;
import std.bigint;

/******************************************************************************/
/* public types */
Expand Down Expand Up @@ -1074,6 +1075,76 @@ struct Json {
return ret.data;
}

/**
Converts this Json object to a std.json.JSONValue object
*/
JSONValue toJSONValue()
const @safe {
final switch (type) {
case Json.Type.undefined:
case Json.Type.null_:
return JSONValue(null);
case Json.Type.bool_:
return JSONValue(get!bool);
case Json.Type.int_:
return JSONValue(get!long);
case Json.Type.bigInt:
auto bi = get!BigInt;
if (bi > long.max)
return JSONValue((() @trusted => cast(ulong)get!BigInt)());
else
return JSONValue((() @trusted => cast(long)get!BigInt)());
case Json.Type.float_:
return JSONValue(get!double);
case Json.Type.string:
return JSONValue(get!string);
case Json.Type.array:
JSONValue[] ret;
foreach (ref const Json e; byValue)
ret ~= e.toJSONValue;
return JSONValue(ret);
case Json.Type.object:
JSONValue[string] ret;
foreach (string k, ref const Json e; byKeyValue) {
if( e.type == Json.Type.undefined ) continue;
ret[k] = e.toJSONValue;
}
return JSONValue(ret);
}
}

/**
Converts a std.json.JSONValue object to a vibe Json object.
*/
static Json fromJSONValue(in JSONValue value)
@safe {
final switch (value.type) {
case JSON_TYPE.NULL:
return Json(null);
case JSON_TYPE.OBJECT:
return (() @trusted {
Json[string] ret;
foreach (string k, ref const JSONValue v; value.object)
ret[k] = Json.fromJSONValue(v);
return Json(ret);
})();
case JSON_TYPE.ARRAY:
return (() @trusted => Json(value.array.map!(a => Json.fromJSONValue(a)).array))();
case JSON_TYPE.STRING:
return Json(value.str);
case JSON_TYPE.INTEGER:
return Json(value.integer);
case JSON_TYPE.UINTEGER:
return Json(BigInt(value.uinteger));
case JSON_TYPE.FLOAT:
return Json(value.floating);
case JSON_TYPE.TRUE:
return Json(true);
case JSON_TYPE.FALSE:
return Json(false);
}
}

private void checkType(TYPES...)(string op = null)
const {
bool matched = false;
Expand Down Expand Up @@ -1795,6 +1866,7 @@ struct JsonStringSerializer(R, bool pretty = false)
m_range.put('"');
}
else static if (is(T == Json)) m_range.writeJsonString(value);
else static if (is(T == JSONValue)) m_range.writeJsonString(Json.fromJSONValue(value));
else static if (isJsonSerializable!T) {
static if (!__traits(compiles, () @safe { return value.toJson(); } ()))
pragma(msg, "Non-@safe toJson/fromJson methods are deprecated - annotate "~T.stringof~".toJson() with @safe.");
Expand Down Expand Up @@ -1930,6 +2002,7 @@ struct JsonStringSerializer(R, bool pretty = false)
}
else static if (is(T == string)) return m_range.skipJsonString(&m_line);
else static if (is(T == Json)) return m_range.parseJson(&m_line);
else static if (is(T == JSONValue)) return m_range.parseJson(&m_line).toJSONValue;
else static if (isJsonSerializable!T) {
static if (!__traits(compiles, () @safe { return T.fromJson(Json.init); } ()))
pragma(msg, "Non-@safe toJson/fromJson methods are deprecated - annotate "~T.stringof~".fromJson() with @safe.");
Expand Down Expand Up @@ -2462,3 +2535,20 @@ private auto trustedRange(R)(R range)
assert(b.foos[0].i == 2);
assert(b.foos[0].foos.length == 0);
}

@system unittest { // Json <-> std.json.JSONValue
auto a = parseJsonString(`{
"null": null,
"string": "Hello",
"integer": 123456,
"uinteger": 18446744073709551614,
"float": 12.34,
"object": { "hello": "world" },
"array": [1, 2, "string"],
"true": true,
"false": false
}`);
assert(Json.fromJSONValue(a.toJSONValue) == a);
auto v = a.toJSONValue;
assert(deserializeJson!JSONValue(serializeToJson(v)) == v);
}

0 comments on commit 4f6ba1d

Please sign in to comment.