JsonizeMe

Undocumented in source.

Members

Aliases

T
alias T = typeof(this)
Undocumented in source.

Functions

convertToJSON
JSONValue convertToJSON()
Undocumented in source. Be warned that the author may not have intended to support it.
convertToJSON
JSONValue convertToJSON()
Undocumented in source. Be warned that the author may not have intended to support it.
populateFromJSON
void populateFromJSON(JSONValue json)
Undocumented in source. Be warned that the author may not have intended to support it.
populateFromJSON
void populateFromJSON(JSONValue json)
Undocumented in source. Be warned that the author may not have intended to support it.

Examples

json conversion of primitive types

import std.math : approxEqual;
enum Category { one, two }

auto j1 = toJSON("bork");
assert(j1.type == JSON_TYPE.STRING && j1.str == "bork");
assert(extract!string(j1) == "bork");

auto j2 = toJSON(4.1);
assert(j2.type == JSON_TYPE.FLOAT && j2.floating.approxEqual(4.1));
assert(extract!float(j2).approxEqual(4.1));
assert(extract!double(j2).approxEqual(4.1));
assert(extract!real(j2).approxEqual(4.1));

auto j3 = toJSON(41);
assert(j3.type == JSON_TYPE.INTEGER && j3.integer == 41);
assert(extract!int(j3) == 41);
assert(extract!long(j3) == 41);

auto j4 = toJSON(41u);
assert(j4.type == JSON_TYPE.UINTEGER && j4.uinteger == 41u);
assert(extract!uint(j4) == 41u);
assert(extract!ulong(j4) == 41u);

auto jenum = toJSON!Category(Category.one);
assert(jenum.type == JSON_TYPE.STRING);
assert(jenum.extract!Category == Category.one);

// homogenous json array
auto j5 = toJSON([9, 8, 7, 6]);
assert(j5.array[0].integer == 9);
assert(j5.array[1].integer == 8);
assert(j5.array[2].integer == 7);
assert(j5.array[3].integer == 6);
assert(j5.type == JSON_TYPE.ARRAY);
assert(extract!(int[])(j5) == [9, 8, 7, 6]);

// heterogenous json array
auto j6 = toJSON("sammich", 1.5, 2, 3u);
assert(j6.array[0].str == "sammich");
assert(j6.array[1].floating.approxEqual(1.5));
assert(j6.array[2].integer == 2);
assert(j6.array[3].uinteger == 3u);

// associative array
int[string] aa = ["a" : 1, "b" : 2, "c" : 3];
auto j7 = toJSON(aa);
assert(j7.type == JSON_TYPE.OBJECT);
assert(j7.object["a"].integer == 1);
assert(j7.object["b"].integer == 2);
assert(j7.object["c"].integer == 3);
assert(extract!(int[string])(j7) == aa);
assert(j7.extract!int("b") == 2);

object serialization -- fields only

1 import std.math : approxEqual;
2 
3 static class Fields {
4   this() { } // class must have a no-args ctor
5 
6   this(int iVal, float fVal, string sVal, int[] aVal, string noJson) {
7     i = iVal;
8     f = fVal;
9     s = sVal;
10     a = aVal;
11     dontJsonMe = noJson;
12   }
13 
14   mixin JsonizeMe;
15 
16   @jsonize { // fields to jsonize -- test different access levels
17     public int i;
18     protected float f;
19     public int[] a;
20     private string s;
21   }
22   string dontJsonMe;
23 
24   override bool opEquals(Object o) {
25     auto other = cast(Fields) o;
26     return i == other.i && s == other.s && a == other.a && f.approxEqual(other.f);
27   }
28 }
29 
30 auto obj = new Fields(1, 4.2, "tally ho!", [9, 8, 7, 6], "blarg");
31 auto json = toJSON!Fields(obj);
32 
33 assert(json.object["i"].integer == 1);
34 assert(json.object["f"].floating.approxEqual(4.2));
35 assert(json.object["s"].str == "tally ho!");
36 assert(json.object["a"].array[0].integer == 9);
37 assert("dontJsonMe" !in json.object);
38 
39 // reconstruct from json
40 auto r = extract!Fields(json);
41 assert(r.i == 1);
42 assert(r.f.approxEqual(4.2));
43 assert(r.s == "tally ho!");
44 assert(r.a == [9, 8, 7, 6]);
45 assert(r.dontJsonMe is null);
46 
47 // array of objects
48 auto a = [
49   new Fields(1, 4.2, "tally ho!", [9, 8, 7, 6], "blarg"),
50       new Fields(7, 42.2, "yea merrily", [1, 4, 6, 4], "asparagus")
51 ];
52 
53 // serialize array of user objects to json
54 auto jsonArray = toJSON!(Fields[])(a);
55 // reconstruct from json
56 assert(extract!(Fields[])(jsonArray) == a);

object serialization with properties

import std.math : approxEqual;

static class Props {
  this() { } // class must have a no-args ctor

  this(int iVal, float fVal, string sVal, string noJson) {
    _i = iVal;
    _f = fVal;
    _s = sVal;
    _dontJsonMe = noJson;
  }

  mixin JsonizeMe;

  @property {
    // jsonize ref property accessing private field
    @jsonize ref int i() { return _i; }
    // jsonize property with non-trivial get/set methods
    @jsonize float f() { return _f - 3; } // the jsonized value will equal _f - 3
    float f(float val) { return _f = val + 5; } // 5 will be added to _f when retrieving from json
    // don't jsonize these properties
    ref string s() { return _s; }
    ref string dontJsonMe() { return _dontJsonMe; }
  }

  private:
  int _i;
  float _f;
  @jsonize string _s;
  string _dontJsonMe;
}

auto obj = new Props(1, 4.2, "tally ho!", "blarg");
auto json = toJSON(obj);

assert(json.object["i"].integer == 1);
assert(json.object["f"].floating.approxEqual(4.2 - 3.0)); // property should have subtracted 3 on retrieval
assert(json.object["_s"].str == "tally ho!");
assert("dontJsonMe" !in json.object);

auto r = extract!Props(json);
assert(r.i == 1);
assert(r._f.approxEqual(4.2 - 3.0 + 5.0)); // property accessor should add 5
assert(r._s == "tally ho!");
assert(r.dontJsonMe is null);

object serialization with custom constructor

import std.math : approxEqual;

static class Custom {
  mixin JsonizeMe;

  this(int i) {
    _i = i;
    _s = "something";
    _f = 10.2;
  }

  @jsonize this(int _i, string _s, float _f = 20.2) {
    this._i = _i;
    this._s = _s ~ " jsonized";
    this._f = _f;
  }

  @jsonize this(double d) { // alternate ctor
    _f = d.to!float;
    _s = d.to!string;
    _i = d.to!int;
  }

  private:
  @jsonize {
    string _s;
    float _f;
    int _i;
  }
}

auto c = new Custom(12);
auto json = toJSON(c);
assert(json.object["_i"].integer == 12);
assert(json.object["_s"].str == "something");
assert(json.object["_f"].floating.approxEqual(10.2));
auto c2 = extract!Custom(json);
assert(c2._i == 12);
assert(c2._s == "something jsonized");
assert(c2._f.approxEqual(10.2));

// test alternate ctor
json = parseJSON(`{"d" : 5}`);
c = json.extract!Custom;
assert(c._f.approxEqual(5) && c._i == 5 && c._s == "5");

struct serialization

import std.math : approxEqual;

static struct S {
  mixin JsonizeMe;

  @jsonize {
    int x;
    float f;
    string s;
  }
  int dontJsonMe;

  this(int x, float f, string s, int noJson) {
    this.x = x;
    this.f = f;
    this.s = s;
    this.dontJsonMe = noJson;
  }
}

auto s = S(5, 4.2, "bogus", 7);
auto json = toJSON(s); // serialize a struct

assert(json.object["x"].integer == 5);
assert(json.object["f"].floating.approxEqual(4.2));
assert(json.object["s"].str == "bogus");
assert("dontJsonMe" !in json.object);

auto r = extract!S(json);
assert(r.x == 5);
assert(r.f.approxEqual(4.2));
assert(r.s == "bogus");
assert(r.dontJsonMe == int.init);

json file I/O

enum file = "test.json";
scope(exit) remove(file);

static struct Data {
  mixin JsonizeMe;

  @jsonize {
    int x;
    string s;
    float f;
  }
}

// write an array of user-defined structs
auto array = [Data(5, "preposterous", 12.7), Data(8, "tesseract", -2.7), Data(5, "baby sloths", 102.7)];
writeJSON(array, file);
auto readBack = readJSON!(Data[])(file);
assert(readBack == array);

// now try an associative array
auto aa = ["alpha": Data(27, "yams", 0), "gamma": Data(88, "spork", -99.999)];
writeJSON(aa, file);
auto aaReadBack = readJSON!(Data[string])(file);
assert(aaReadBack == aa);

inheritance

import std.math : approxEqual;
static class Parent {
  mixin JsonizeMe;
  @jsonize {
    int x;
    string s;
  }
}

static class Child : Parent {
  mixin JsonizeMe;
  @jsonize {
    float f;
  }
}

auto c = new Child;
c.x = 5;
c.s = "hello";
c.f = 2.1;

auto json = c.toJSON;
assert(json.extract!int("x") == 5);
assert(json.extract!string("s") == "hello");
assert(json.extract!float("f").approxEqual(2.1));

auto child = json.extract!Child;
assert(child.x == 5 && child.s == "hello" && child.f.approxEqual(2.1));

auto parent = json.extract!Parent;
assert(parent.x == 5 && parent.s == "hello");

inheritance with ctors

import std.math : approxEqual;
static class Parent {
  mixin JsonizeMe;

  @jsonize this(int x, string s) {
    _x = x;
    _s = s;
  }

  @jsonize @property {
    int x()    { return _x; }
    string s() { return _s; }
  }

  private:
  int _x;
  string _s;
}

static class Child : Parent {
  mixin JsonizeMe;

  @jsonize this(int x, string s, float f) {
    super(x, s);
    _f = f;
  }

  @jsonize @property {
    float f() { return _f; }
  }

  private:
  float _f;
}

auto c = new Child(5, "hello", 2.1);

auto json = c.toJSON;
assert(json.extract!int("x") == 5);
assert(json.extract!string("s") == "hello");
assert(json.extract!float("f").approxEqual(2.1));

auto child = json.extract!Child;
assert(child.x == 5 && child.s == "hello" && child.f.approxEqual(2.1));

auto parent = json.extract!Parent;
assert(parent.x == 5 && parent.s == "hello");

renamed members

static class Bleh {
  mixin JsonizeMe;
  private {
    @jsonize("x") int _x;
    @jsonize("s") string _s;
  }
}

auto b = new Bleh;
b._x = 5;
b._s = "blah";

auto json = b.toJSON;

assert(json.extract!int("x") == 5);
assert(json.extract!string("s") == "blah");

auto reconstruct = json.extract!Bleh;
assert(reconstruct._x == b._x && reconstruct._s == b._s);

Meta