voile.json

JSONValueのヘルパー、シリアライズ・デシリアライズ
@property JSONValue json(T)(auto const ref T[] x)
if(isSomeString!(T[]));
@property JSONValue json(T)(auto const ref T x)
if(isIntegral!T && !is(T == enum) || isFloatingPoint!T || is(Unqual!T == bool));
@property JSONValue json(T)(auto const ref T x)
if(is(T == enum));
@property JSONValue json(T)(auto const ref T[] ary)
if(!isSomeString!(T[]) && isArray!(T[]));
@property JSONValue json(Value, Key)(auto const ref Value[Key] aa)
if(isSomeString!Key && is(typeof(() { auto v = Value.init.json; } )));
@property JSONValue json(JV)(auto const ref JV v)
if(is(JV : const(JSONValue)));
JSONValueデータを得る
Examples:
dstring dstr = "あいうえお";
wstring wstr = "かきくけこ";
string  str  = "さしすせそ";
auto dstrjson = dstr.json;
auto wstrjson = wstr.json;
auto strjson  = str.json;
assert(dstrjson.type == JSONType.string);
assert(wstrjson.type == JSONType.string);
assert(strjson.type  == JSONType.string);
assert(dstrjson.str == "あいうえお");
assert(wstrjson.str == "かきくけこ");
assert(strjson.str  == "さしすせそ");
Examples:
bool bt = true;
bool bf;
auto btjson = bt.json;
auto bfjson = bf.json;
assert(btjson.type == JSONType.true_);
assert(bfjson.type == JSONType.false_);
Examples:
import std.typetuple;
foreach (T; TypeTuple!(ubyte, byte, ushort, short, uint, int, ulong, long))
{
	T x = 123;
	auto xjson = x.json;
	static if (isUnsigned!T)
	{
		assert(xjson.type == JSONType.uinteger);
		assert(xjson.uinteger == 123);
	}
	else
	{
		assert(xjson.type == JSONType.integer);
		assert(xjson.integer == 123);
	}
}
foreach (T; TypeTuple!(float, double, real))
{
	T x = 0.125;
	auto xjson = x.json;
	assert(xjson.type == JSONType.float_);
	assert(xjson.floating == 0.125);
}
Examples:
enum EnumType
{
	a, b, c
}
auto a = EnumType.a;
auto ajson = a.json;
assert(ajson.type == JSONType.string);
assert(ajson.str == "a");
Examples:
auto ary = [1,2,3];
auto aryjson = ary.json;
assert(aryjson.type == JSONType.array);
assert(aryjson[0].type == JSONType.integer);
assert(aryjson[1].type == JSONType.integer);
assert(aryjson[2].type == JSONType.integer);
assert(aryjson[0].integer == 1);
assert(aryjson[1].integer == 2);
assert(aryjson[2].integer == 3);
Examples:
auto ary = ["ab","cd","ef"];
auto aryjson = ary.json;
assert(aryjson.type == JSONType.array);
assert(aryjson[0].type == JSONType.string);
assert(aryjson[1].type == JSONType.string);
assert(aryjson[2].type == JSONType.string);
assert(aryjson[0].str == "ab");
assert(aryjson[1].str == "cd");
assert(aryjson[2].str == "ef");
Examples:
struct A
{
	int a = 123;
	JSONValue json() const @property
	{
		return JSONValue(["a": JSONValue(a)]);
	}
	void json(JSONValue v) @property
	{
		a = v.getValue("a", 123);
	}
}
auto ary = [A(1),A(2),A(3)];
auto aryjson = ary.json;
assert(aryjson.type == JSONType.array);
assert(aryjson[0].type == JSONType.object);
assert(aryjson[1].type == JSONType.object);
assert(aryjson[2].type == JSONType.object);
assert(aryjson[0]["a"].type == JSONType.integer);
assert(aryjson[1]["a"].type == JSONType.integer);
assert(aryjson[2]["a"].type == JSONType.integer);
assert(aryjson[0]["a"].integer == 1);
assert(aryjson[1]["a"].integer == 2);
assert(aryjson[2]["a"].integer == 3);
Examples:
int[string] val;
val["xxx"] = 10;
auto jv = val.json;
assert(jv["xxx"].integer == 10);
pure nothrow @trusted void setValue(T)(ref JSONValue v, string name, T val);
JSONValueデータの操作
Examples:
JSONValue json;
json.setValue("dat", 123);
assert(json.type == JSONType.object);
assert("dat" in json.object);
assert(json["dat"].type == JSONType.integer);
assert(json["dat"].integer == 123);
Examples:
enum Type
{
	foo, bar,
}
JSONValue json;
json.setValue("type", Type.foo);
assert(json.type == JSONType.object);
assert("type" in json.object);
assert(json["type"].type == JSONType.string);
assert(json["type"].str == "foo");
Examples:
struct A
{
	int a = 123;
	JSONValue json() const @property
	{
		JSONValue v;
		v.setValue("a", a);
		return v;
	}
}
A a;
a.a = 321;
JSONValue json;
json.setValue("a", a);
Examples:
JSONValue json;
json.setValue("test", "あいうえお");
static assert(is(typeof(json.getValue("test", "かきくけこ"d)) == dstring));
static assert(is(typeof(json.getValue("test", "かきくけこ"w)) == wstring));
static assert(is(typeof(json.getValue("test", "かきくけこ"c)) == string));
assert(json.getValue("test", "かきくけこ"d) == "あいうえお"d);
assert(json.getValue("test", "かきくけこ"w) == "あいうえお"w);
assert(json.getValue("test", "かきくけこ"c) == "あいうえお"c);
assert(json.getValue("hoge", "かきくけこ"c) == "かきくけこ"c);
bool fromJson(T)(in JSONValue src, ref T dst)
if(isSomeString!T);
bool fromJson(T)(in JSONValue src, ref T dst)
if(isIntegral!T && !is(T == enum));
bool fromJson(T)(in JSONValue src, ref T dst)
if(isFloatingPoint!T);
bool fromJson(T)(in JSONValue src, ref T dst)
if(is(T == struct) && !is(Unqual!T : JSONValue) && !isManagedUnion!T);
bool fromJson(T)(in JSONValue src, ref T dst)
if(is(T == class));
bool fromJson(T)(in JSONValue src, ref T dst)
if(is(T == enum));
bool fromJson(T)(in JSONValue src, ref T dst)
if(is(T == bool));
bool fromJson(T)(in JSONValue src, ref T dst)
if(!isSomeString!T && isDynamicArray!T);
bool fromJson(Value, Key)(in JSONValue src, ref Value[Key] dst)
if(isSomeString!Key && is(typeof(() { JSONValue val; cast(void)fromJson(val, dst[Key.init]); } )));
bool fromJson(T)(in JSONValue src, ref T dst)
if(is(Unqual!T == JSONValue));
Examples:
auto jv = JSONValue("xxx");
string dst;
auto res = fromJson(jv, dst);
assert(res);
assert(dst == "xxx");
Examples:
auto jv = JSONValue(10);
int dst;
auto res = fromJson(jv, dst);
assert(res);
assert(dst == 10);
Examples:
import std.math: isClose;
auto jv = JSONValue(10.0);
double dst;
auto res = fromJson(jv, dst);
assert(res);
assert(dst.isClose(10.0));
Examples:
auto jv = JSONValue(["x": 10, "y": 20]);
static struct Point{ int x, y; }
Point pt;
auto res = fromJson(jv, pt);
assert(res);
assert(pt.x == 10);
assert(pt.y == 20);
pure nothrow @trusted T getValue(T)(in JSONValue v, string name, lazy scope T defaultVal = T.init);
Examples:
JSONValue json;
json.setValue("test", 123);
static assert(is(typeof(json.getValue("test", 654UL)) == ulong));
static assert(is(typeof(json.getValue("test", 654U)) == uint));
static assert(is(typeof(json.getValue("test", cast(byte)12)) == byte));
assert(json.getValue("test", 654UL) == 123);
assert(json.getValue("test", 654U) == 123);
assert(json.getValue("test", cast(byte)12) == 123);
assert(json.getValue("hoge", cast(byte)12) == 12);
Examples:
JSONValue json;
json.setValue("test", 0.125);
static assert(is(typeof(json.getValue("test", 0.25f)) == float));
static assert(is(typeof(json.getValue("test", 0.25)) == double));
static assert(is(typeof(json.getValue("test", 0.25L)) == real));
assert(json.getValue("test", 0.25f) == 0.125f);
assert(json.getValue("test", 0.25) == 0.125);
assert(json.getValue("test", 0.25L) == 0.125L);
assert(json.getValue("hoge", 0.25L) == 0.25L);
Examples:
struct A
{
	int a = 123;
	JSONValue json() const @property
	{
		JSONValue v;
		v.setValue("a", a);
		return v;
	}
	void json(JSONValue v) @property
	{
		a = v.getValue("a", 123);
	}
}
A a;
a.a = 321;
JSONValue json;
json.setValue("a", a);
static assert(is(typeof(json.getValue("a", A(456))) == A));
assert(json.getValue("a", A(456)).a == 321);
assert(json.getValue("b", A(456)).a == 456);
Examples:
static class A
{
	int a = 123;
	JSONValue json() const @property
	{
		JSONValue v;
		v.setValue("a", a);
		return v;
	}
	void json(JSONValue v) @property
	{
		a = v.getValue("a", 123);
	}
}
auto a = new A;
a.a = 321;
JSONValue json;
json.setValue("a", a);
static assert(is(typeof(json.getValue!A("a")) == A));
assert(json.getValue!A("a").a == 321);
assert(json.getValue!A("b") is null);
Examples:
enum Type
{
	foo, bar
}
JSONValue json;
json.setValue("a", Type.bar);
static assert(is(typeof(json.getValue("a", Type.foo)) == Type));
assert(json.getValue("a", Type.foo) == Type.bar);
assert(json.getValue("b", Type.foo) == Type.foo);
Examples:
JSONValue json;
json.setValue("t", true);
json.setValue("f", false);
static assert(is(typeof(json.getValue("t", true)) == bool));
static assert(is(typeof(json.getValue("f", false)) == bool));
assert(json.getValue("t", true) == true);
assert(json.getValue("f", true) == false);
assert(json.getValue("t", false) == true);
assert(json.getValue("f", false) == false);
assert(json.getValue("x", true) == true);
assert(json.getValue("x", false) == false);
Examples:
JSONValue json;
json.setValue("test1", [1,2,3]);
auto x = json.getValue("test1", [2,3,4]);

static assert(is(typeof(json.getValue("test1", [2,3,4])) == int[]));
assert(json.getValue("test1", [2,3,4]) == [1,2,3]);
assert(json.getValue("test1x", [2,3,4]) == [2,3,4]);

json.setValue("test2", [0.5,0.25,0.125]);
static assert(is(typeof(json.getValue("test2", [0.5,0.5,0.5])) == double[]));
assert(json.getValue("test2", [0.5,0.5,0.5]) == [0.5,0.25,0.125]);
assert(json.getValue("test2x", [0.5,0.5,0.5]) == [0.5,0.5,0.5]);

json.setValue("test3", ["ab","cd","ef"]);
static assert(is(typeof(json.getValue("test3", ["あい","うえ","おか"])) == string[]));
assert(json.getValue("test3", ["あい","うえ","おか"]) == ["ab","cd","ef"]);
assert(json.getValue("test3x", ["あい","うえ","おか"]) == ["あい","うえ","おか"]);

json.setValue("test4", [true, false, true]);
static assert(is(typeof(json.getValue("test4", [false, true, true])) == bool[]));
assert(json.getValue("test4", [false, true, true]) == [true, false, true]);
assert(json.getValue("test4x", [false, true, true]) == [false, true, true]);
Examples:
static struct A
{
	int a = 123;
	JSONValue json() const @property
	{
		JSONValue v;
		v.setValue("a", a);
		return v;
	}
	void json(JSONValue v) @property
	{
		assert(v.type == JSONType.object);
		a = v.getValue("a", 123);
	}
}
auto a = [A(1),A(2),A(3)];
JSONValue json;
json.setValue("a", a);
static assert(is(typeof(json.getValue("a", [A(4),A(5),A(6)])) == A[]));
assert(json.getValue("a", [A(4),A(5),A(6)]) == [A(1),A(2),A(3)]);
assert(json.getValue("b", [A(4),A(5),A(6)]) == [A(4),A(5),A(6)]);
alias JSONValueArray = const(JSONValue)[];
alias JSONValueObject = std.typecons.Rebindable!(const(JSONValue[string])).Rebindable;
bool getArray(JSONValue json, string name, ref JSONValueArray ary);
bool getObject(JSONValue json, string name, ref JSONValueObject object);
struct AttrConverter(T);
T function(in JSONValue v) from;
JSONValue function(in T v) to;
AttrConverter!T converter(T)(T function(in JSONValue) from, JSONValue function(in T) to);
Attribute converting method
auto kind(T)(string name, T value);
auto kind(T)(T value);
JSONValue serializeToJson(T)(in T data);
string serializeToJsonString(T)(in T data, JSONOptions options = JSONOptions.none);
void serializeToJsonFile(T)(in T data, string jsonfile, JSONOptions options = JSONOptions.none);
serialize data to JSON
void deserializeFromJson(T)(ref T data, in JSONValue json);
T deserializeFromJson(T)(in JSONValue jv);
void deserializeFromJsonString(T)(ref T data, string jsonContents);
T deserializeFromJsonString(T)(string jsonContents);
void deserializeFromJsonFile(T)(ref T data, string jsonFile);
T deserializeFromJsonFile(T)(string jsonFile);
deserialize data from JSON
Examples:
import std.exception, std.datetime.systime;
struct UnionDataA{ @key @value!1 int a; @name("hogeB") int b; }
struct UnionDataB{ @key @value!2 int a; int c; }
alias TE = TypeEnum!(UnionDataA, UnionDataB);
enum EnumDataA { @data!int x, @data!string str }
alias ED = Endata!EnumDataA;

static struct Point
{
	@name("xValue")
	int x;
	@name("yValue")
	int y = 10;
}
static struct Data
{
	string key;
	int    value;
	@ignore    int    testval;
	@essential Point  pt;
	Point[] points;
	Point[string] pointMap;
	TE te;
	ED ed;
	
	@converter!SysTime(jv=>SysTime.fromISOExtString(jv.str),
	                   v =>JSONValue(v.toISOExtString()))
	SysTime time;
}
Data x, y, z;
x.key = "xxx";
x.value = 200;
x.pt.x = 300;
x.pt.y = 400;
x.testval = 100;
x.te = UnionDataA(1, 2);
x.ed.initialize!(EnumDataA.str)("test");
auto tim = Clock.currTime();
x.time = tim;
y.testval = 200;
JSONValue jv1     = serializeToJson(x);
string    jsonStr = jv1.toPrettyString();
JSONValue jv2     = parseJSON(jsonStr);
y = deserializeFromJson!Data(jv2);
assert(x != y);
y.testval = x.testval;
assert(x == y);
assert(jv1["pt"]["xValue"].integer == 300);
assert(jv1["pt"]["yValue"].integer == 400);
assert(jv1["time"].str == tim.toISOExtString());
assert(jv1["te"]["hogeB"].integer == 2);
assert(jv1["ed"]["str"].str == "test");

auto e1 = z.deserializeFromJson(parseJSON(`{}`)).collectException;
import std.stdio;
assert(e1);
assert(e1.msg == "Key not found: pt");

auto e2json = parseJSON(`{"pt": {}}`);
auto e2 = z.deserializeFromJson(e2json).collectException;
assert(!e2);
assert(z.pt.y == 10);
assert(z.time == SysTime.init);

scope (exit)
{
	import std.file;
	if ("test.json".exists)
		"test.json".remove();
}

x.serializeToJsonFile("test.json", JSONOptions.doNotEscapeSlashes);
z = deserializeFromJsonFile!Data("test.json");
assert(x != z);
z.testval = x.testval;
assert(x == z);

Data[] datAry1, datAry2;
Data[string] datMap1, datMap2;
auto teInitDat = TE(UnionDataA(1,7));
ED edInitDat;
edInitDat.initialize!(EnumDataA.str)("test");
datAry1 = [Data("x", 10, 0, Point(1,2), [Point(3,4)], ["PT": Point(5,6)], teInitDat, edInitDat, tim)];
datMap1 = ["Data": Data("x", 10, 0, Point(1,2), [Point(3,4)], ["PT": Point(5,6)], teInitDat, edInitDat, tim)];
datAry1.serializeToJsonFile("test.json");
datAry2.deserializeFromJsonFile("test.json");
datMap1.serializeToJsonFile("test.json");
datMap2.deserializeFromJsonFile("test.json");
assert(datAry1[0].points[0] == Point(3,4));
assert(datAry1[0].pointMap["PT"] == Point(5,6));
assert(datMap1["Data"].points[0] == Point(3,4));
assert(datMap1["Data"].pointMap["PT"] == Point(5,6));
assert(datAry2[0].points[0] == Point(3,4));
assert(datAry2[0].pointMap["PT"] == Point(5,6));
assert(datMap2["Data"].points[0] == Point(3,4));
assert(datMap2["Data"].pointMap["PT"] == Point(5,6));
@property JSONValue deepCopy(in JSONValue v);
struct JWTValue;
JWT
Examples: ditto
import std.exception;
static immutable testjwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9"
	~".eyJ0ZXN0a2V5IjoidGVzdHZhbHVlIn0"
	~".AXHSKa2ubvg6jMckkYaWgCXluhOamfFDk8y163X4DPs";

auto jwt = JWTValue(JWTValue.Algorithm.HS256, "testsecret");
jwt["testkey"] = "testvalue";
assert(jwt.toString() == testjwt);

auto jwt2 = JWTValue(testjwt, "testsecret");
assert(jwt2["testkey"].str == "testvalue");
assert(jwt2.toString() == jwt.toString());

assertThrown(JWTValue(testjwt, "testsecret2"));
enum Algorithm: int;
Algorithm algorithm;
this(const(char)[] jwt, const(ubyte)[] key);
this(const(char)[] jwt, const(char)[] key);
this(Algorithm algo, const(ubyte)[] key);
this(Algorithm algo, const(ubyte)[] key, JSONValue payload);
this(Algorithm algo, const(ubyte)[] key, JSONValue[string] payload);
this(Algorithm algo, const(char)[] key);
this(Algorithm algo, const(char)[] key, JSONValue payload);
this(Algorithm algo, const(char)[] key, JSONValue[string] payload);
void key(string key);
void key(const(ubyte)[] key);
dittp
inout ref inout(JSONValue) opIndex(string name) return;
void opIndexAssign(T)(auto ref T value, string name) return;
inout ref inout(JSONValue) payload() return;
const string toString();
void setValue(T)(ref JWTValue dat, string name, T val);
T getValue(T)(in JWTValue dat, string name, lazy T defaultVal);
JWTValue serializeToJwt(T)(in T data, JWTValue.Algorithm algo, const(ubyte)[] key);
JWTValue serializeToJwt(T)(in T data, JWTValue.Algorithm algo, const(char)[] key);
JWTValue serializeToJwt(T)(in T data, const(ubyte)[] key);
JWTValue serializeToJwt(T)(in T data, const(char)[] key);
string serializeToJwtString(T)(in T data, JWTValue.Algorithm algo, const(ubyte)[] key);
string serializeToJwtString(T)(in T data, JWTValue.Algorithm algo, const(char)[] key);
string serializeToJwtString(T)(in T data, const(ubyte)[] key);
string serializeToJwtString(T)(in T data, const(char)[] key);
void deserializeFromJwt(T)(ref T data, JWTValue jwt);
void deserializeFromJwtString(T)(ref T data, const(char)[] jwt, const(char)[] key);
シリアライズ/デシリアライズ
Examples: ditto
import std.exception;
static immutable testjwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9"
	~".eyJ0ZXN0a2V5IjoidGVzdHZhbHVlIn0"
	~".AXHSKa2ubvg6jMckkYaWgCXluhOamfFDk8y163X4DPs";

struct Dat { string testkey; }
auto dat = Dat("testvalue");

auto jwt1 = serializeToJwt(dat, JWTValue.Algorithm.HS256, "testsecret");
assert(jwt1.toString() == testjwt);
auto jwt2 = serializeToJwt(dat, "testsecret");
assert(jwt2.toString() == testjwt);
assert(serializeToJwtString(dat, JWTValue.Algorithm.HS256, "testsecret") == testjwt);
assert(serializeToJwtString(dat, "testsecret") == testjwt);

Dat dat2;
dat2.deserializeFromJwt(jwt1);
assert(dat2 == dat);

Dat dat3;
dat3.deserializeFromJwtString(testjwt, "testsecret");
assert(dat3 == dat);