fromJSON

Convert from JSONValue to any other type

T
fromJSON
(
in JSONValue json
)

Examples

Converting common types

assertEqual(fromJSON!int(JSONValue(1)), 1);
assertEqual(fromJSON!double(JSONValue(1.0)), 1);
assertEqual(fromJSON!double(JSONValue(1.3)), 1.3);
assertEqual(fromJSON!string(JSONValue("str")), "str");
assertEqual(fromJSON!bool(JSONValue(true)), true);
assertEqual(fromJSON!bool(JSONValue(false)), false);
assertEqual(fromJSON!JSONValue(JSONValue(true)), JSONValue(true));

Converting arrays

assertEqual(fromJSON!(int[])(toJSON([1, 2])), [1, 2]);
assertEqual(fromJSON!(Point[])(parseJSON(q{[{"x":-1,"y":2},{"x":3,"y":4}]})), [Point(-1,2),Point(3,4)]);

Array as member of other class

// Types need to be defined in different module, otherwise 
// type is not known at compile time
import painlessjson.unittesttypes_local_import;

string jsonString = q{[ {"duration": "10"} ]};
Route[] routes = parseJSON(jsonString).fromJSON!(Route[]);
assertEqual(routes.length, 1);

jsonString = q{{"routes":[ {"duration": "10"} ] }};
JourneyPlan jp;
jp = parseJSON(jsonString).fromJSON!JourneyPlan;
assertEqual(jp.routes.length, 1);

Associative arrays

string[int] aaInt = [0 : "a", 1 : "b"];
assertEqual(aaInt, fromJSON!(string[int])(parseJSON(q{{"0" : "a", "1": "b"}})));

string[string] aaString = ["hello" : "world", "json" : "painless"];
assertEqual(aaString, fromJSON!(string[string])(parseJSON(q{{"hello" : "world", "json" : "painless"}})));

Associative array containing struct

auto parsed = fromJSON!(SimpleStruct[string])(parseJSON(q{{"key": {"str": "value"}}}));
assertEqual(parsed , ["key": SimpleStruct("value")]);

Associative array with struct key

JSONValue value = parseJSON(q{{"{\"str\":\"key\"}":"value", "{\"str\":\"key2\"}":"value2"}});
auto parsed = fromJSON!(string[SimpleStruct])(value);
assertEqual(
    parsed
    , [SimpleStruct("key"): "value", SimpleStruct("key2"): "value2"]);

struct with inner struct and AA

auto testStruct = StructWithStructAndAA(["key1": "value1"], ["key2": StructWithStructAndAA.Inner("value2")]);
auto testJSON = parseJSON(q{{"stringToInner":{"key2":{"str":"value2"}},"stringToString":{"key1":"value1"}}});
assertEqual(fromJSON!StructWithStructAndAA(testJSON), testStruct);

Error reporting from inner objects

import std.exception : collectExceptionMsg;
import std.algorithm : canFind;
void throwFunc() {
    fromJSON!(string[SimpleStruct])(parseJSON(q{{"{\"str\": \"key1\"}": "value", "key2":"value2"}}));
}
auto errorMessage = collectExceptionMsg(throwFunc());
assert(errorMessage.canFind("key2"));
assert(errorMessage.canFind("string[SimpleStruct]"));
assert(!errorMessage.canFind("key1"));

Structs from JSON

auto p = fromJSON!Point(parseJSON(q{{"x":-1,"y":2}}));
assertEqual(p.x, -1);
assertEqual(p.y, 2);
p = fromJSON!Point(parseJSON(q{{"x":2}}));
assertEqual(p.x, 2);
assertEqual(p.y, 1);
p = fromJSON!Point(parseJSON(q{{"y":3}}));
assertEqual(p.x, 0);
assertEqual(p.y, 3);
p = fromJSON!Point(parseJSON(q{{"x":-1,"y":2,"z":3}}));
assertEqual(p.x, -1);
assertEqual(p.y, 2);

Class from JSON

auto p = fromJSON!PointC(parseJSON(q{{"x":-1,"y":2}}));
assertEqual(p.x, -1);
assertEqual(p.y, 2);

Convert class from JSON using "fromJSON"

auto p = fromJSON!PointPrivate(parseJSON(q{{"x":-1,"y":2}}));
assertEqual(p.x, -1);
assertEqual(p.y, 2);

Convert struct from JSON using properties

auto p = fromJSON!PointPrivateProperty(parseJSON(q{{"x":-1,"y":2,"z":3}}));
assertEqual(p.x, -1);
assertEqual(p.y, 2);

User class with SerializedName annotation

auto p = fromJSON!PointSerializationName(parseJSON(q{{"xOut":-1,"yOut":2}}));
assertEqual(p.x, 2);
assertEqual(p.y, -1);

User class with SerializeIgnore annotations

auto p = fromJSON!PointSerializationIgnore(parseJSON(q{{"z":15}}));
assertEqual(p.x, 0);
assertEqual(p.y, 1);
assertEqual(p.z, 15);

Unnamed tuples

Tuple!(int, int) point;
point[0] = 5;
point[1] = 6;
assertEqual(point, fromJSON!(Tuple!(int, int))(parseJSON(q{{"_0":5,"_1":6}})));

No default constructor

auto p = fromJSON!PointUseConstructor(parseJSON(q{{"x":2, "y":5}}));
assertEqual(p.x, 2);
assertEqual(p.y, 5);

Multiple constructors and all JSON-values are there

auto person = fromJSON!IdAndName(parseJSON(q{{"id":34, "name": "Jason Pain"}}));
assertEqual(person.id, 34);
assertEqual(person.name, "Jason Pain");

Multiple constructors and some JSON-values are missing

auto person = fromJSON!IdAndName(parseJSON(q{{"id":34}}));
assertEqual(person.id, 34);
assertEqual(person.name, "Undefined");

Accept underscore and convert it to camelCase automatically

auto value = fromJSON!CamelCaseConversion(parseJSON(q{{"was_camel_case":8,"was_underscore":9}}));
assertEqual(value.wasCamelCase, 8);
assertEqual(value.was_underscore, 9);

Meta