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

class A
{
    double x = 0;
    double y = 1;
    JSONValue toJSON()
    {
        JSONValue[string] json;
        json["x"] = x;
        return JSONValue(json);
    }

}

auto a = new A;
assertEqual(a.toJSON.toString, q{{"x":0}});

class B
{
    double x = 0;
    double y = 1;
}

// Both templates will now work for B, so this is ambiguous in D.
// Under dmd it looks like the toJSON!T that is loaded first is the one used
JSONValue toJSON(T : B)(T b)
{
    JSONValue[string] json;
    json["x"] = b.x;
    return JSONValue(json);
}

auto b = new B;
assertEqual(b.toJSON.toString, q{{"x":0,"y":1}});

class Z
{
    double x = 0;
    double y = 1;
    // Adding an extra value
    JSONValue toJSON()
    {
        JSONValue[string] json = painlessjson.toJSON!Z(this).object;
        json["add"] = "bla".toJSON;
        return JSONValue(json);
    }

}

auto z = new Z;
assertEqual(z.toJSON["x"].floating, 0);
assertEqual(z.toJSON["y"].floating, 1);
assertEqual(z.toJSON["add"].str, "bla");

Meta