toJSON

Template function that converts any object to JSON

JSONValue
toJSON
(
in T t
)

Examples

Converting common types

assertEqual(5.toJSON!int, JSONValue(5));
assert(4.toJSON != JSONValue(5)); //TODO: Wait for DUnit to implement assertNotEqual
assertEqual(5.4.toJSON, JSONValue(5.4));
assertEqual(toJSON("test"), JSONValue("test"));
assertEqual(toJSON(JSONValue("test")), JSONValue("test"));

Converting InputRanges

assertEqual([1, 2].toJSON.toString, "[1,2]");

User structs

Point p;
assertEqual(toJSON(p).toString, q{{"x":0,"y":1}});

Array of structs

Point[] ps = [Point(-1, 1), Point(2, 3)];
assertEqual(toJSON(ps).toString, q{[{"x":-1,"y":1},{"x":2,"y":3}]});

User class

PointC p = new PointC(1, -2);
assertEqual(toJSON(p).toString, q{{"x":1,"y":-2}});

User class with private fields

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

User class with defaultToJSON

PointDefaultFromJSON p = new PointDefaultFromJSON(-1, 2);
assertEqual(toJSON(p).toString, q{{"_x":-1,"y":2}});
auto pnt = p.toJSON.fromJSON!PointDefaultFromJSON;
assertEqual(p.x, -1);
assertEqual(p.y, 2);

User class with private fields and @property

auto p = PointPrivateProperty(-1, 2);
assertEqual(toJSON(p).toString, q{{"x":-1,"y":2,"z":1}});

User class with SerializedName annotation

auto p = PointSerializationName(-1, 2);
assertEqual(toJSON(p)["xOut"].floating, -1);
assertEqual(toJSON(p)["yOut"].floating, 2);

User class with SerializeIgnore annotations

auto p = PointSerializationIgnore(-1, 5, 4);
assertEqual(toJSON(p).toString, q{{"z":5}});

Array of classes

PointC[] ps = [new PointC(-1, 1), new PointC(2, 3)];
assertEqual(toJSON(ps).toString, q{[{"x":-1,"y":1},{"x":2,"y":3}]});

Associative array

string[int] aa = [0 : "a", 1 : "b"];
assert(aa.toJSON.toString == q{{"0":"a","1":"b"}});
Point[int] aaStruct = [0 : Point(-1, 1), 1 : Point(2, 0)];
assertEqual(aaStruct.toJSON.toString, q{{"0":{"x":-1,"y":1},"1":{"x":2,"y":0}}});
assertEqual(["key": "value"].toJSON.toString, q{{"key":"value"}});

Associative array containing struct

assertEqual(["test": SimpleStruct("test2")].toJSON().toString, q{{"test":{"str":"test2"}}});

Associative array with struct key

assertEqual([SimpleStruct("key"): "value", SimpleStruct("key2"): "value2"].toJSON().toString, q{{"{\"str\":\"key\"}":"value","{\"str\":\"key2\"}":"value2"}});

struct with inner struct and AA

auto testStruct = StructWithStructAndAA(["key1": "value1"], ["key2": StructWithStructAndAA.Inner("value2")]);
auto converted = testStruct.toJSON();
assertEqual(converted["stringToInner"].toString, q{{"key2":{"str":"value2"}}});
assertEqual(converted["stringToString"].toString, q{{"key1":"value1"}});

Unnamed tuples

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

Named tuples

Tuple!(int, "x", int, "y") point;
point.x = 5;
point.y = 6;
assertEqual(point, fromJSON!(Tuple!(int, "x", int, "y"))(parseJSON(q{{"x":5,"y":6}})));

Convert camel case to underscore automatically

CamelCaseConversion value;
value.wasCamelCase = 5;
value.was_underscore = 7;

auto valueAsJSON = value.toJSON!(CamelCaseConversion,SerializationOptions(false, true));

assertEqual(valueAsJSON["was_camel_case"].integer, 5); 
assertEqual(valueAsJSON["was_underscore"].integer, 7);

Overloaded toJSON

1 class A
2 {
3     double x = 0;
4     double y = 1;
5     JSONValue toJSON()
6     {
7         JSONValue[string] json;
8         json["x"] = x;
9         return JSONValue(json);
10     }
11 
12 }
13 
14 auto a = new A;
15 assertEqual(a.toJSON.toString, q{{"x":0}});
16 
17 class B
18 {
19     double x = 0;
20     double y = 1;
21 }
22 
23 // Both templates will now work for B, so this is ambiguous in D.
24 // Under dmd it looks like the toJSON!T that is loaded first is the one used
25 JSONValue toJSON(T : B)(T b)
26 {
27     JSONValue[string] json;
28     json["x"] = b.x;
29     return JSONValue(json);
30 }
31 
32 auto b = new B;
33 assertEqual(b.toJSON.toString, q{{"x":0,"y":1}});
34 
35 class Z
36 {
37     double x = 0;
38     double y = 1;
39     // Adding an extra value
40     JSONValue toJSON()
41     {
42         JSONValue[string] json = painlessjson.toJSON!Z(this).object;
43         json["add"] = "bla".toJSON;
44         return JSONValue(json);
45     }
46 
47 }
48 
49 auto z = new Z;
50 assertEqual(z.toJSON["x"].floating, 0);
51 assertEqual(z.toJSON["y"].floating, 1);
52 assertEqual(z.toJSON["add"].str, "bla");

Meta