From f2858c7440ea6c439c1b111db6e0eed84c3e0051 Mon Sep 17 00:00:00 2001 From: Daniel Davidson Date: Wed, 2 Oct 2013 21:36:40 -0500 Subject: [PATCH 1/3] added support for enums (or other string convertable types) as keys to maps for json serialization --- source/vibe/data/json.d | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/source/vibe/data/json.d b/source/vibe/data/json.d index 03d508ad13..574ed08187 100644 --- a/source/vibe/data/json.d +++ b/source/vibe/data/json.d @@ -899,8 +899,8 @@ Json serializeToJson(T)(T value) return Json(ret); } else static if( isAssociativeArray!TU ){ Json[string] ret; - foreach( string key, value; value ) - ret[key] = serializeToJson(value); + foreach( key, value; value ) + ret[to!string(key)] = serializeToJson(value); return Json(ret); } else static if(isJsonSerializable!TU) { return value.toJson(); @@ -963,9 +963,9 @@ T deserializeJson(T)(Json src) return dst; } else static if( isAssociativeArray!T ){ alias typeof(T.init.values[0]) TV; - Unqual!TV[string] dst; + Unqual!TV[KeyType!T] dst; foreach( string key, value; src ) - dst[key] = deserializeJson!(Unqual!TV)(value); + dst[to!(KeyType!T)(key)] = deserializeJson!(Unqual!TV)(value); return dst; } else static if (isJsonSerializable!T) { return T.fromJson(src); @@ -1057,6 +1057,35 @@ unittest { assert(c.b == d.b); } +unittest { + enum Color { Red, Green, Blue } + { + static class T { + string[Color] enumIndexedMap; + this() { + enumIndexedMap = [ Color.Red : "magenta", Color.Blue : "deep blue" ]; + } + } + + T original = new T; + original.enumIndexedMap[Color.Green] = "olive"; + T other; + deserializeJson(other, serializeToJson(original)); + assert(serializeToJson(other) == serializeToJson(original)); + } + { + static struct S { + string[Color] enumIndexedMap; + } + + S *original = new S; + original.enumIndexedMap = [ Color.Red : "magenta", Color.Blue : "deep blue" ]; + original.enumIndexedMap[Color.Green] = "olive"; + S other; + deserializeJson(other, serializeToJson(original)); + assert(serializeToJson(other) == serializeToJson(original)); + } +} /** Writes the given JSON object as a JSON string into the destination range. From ff7918e8a9cef86581141337fe21e04829a5776a Mon Sep 17 00:00:00 2001 From: Daniel Davidson Date: Thu, 3 Oct 2013 06:51:53 -0500 Subject: [PATCH 2/3] for AAs add support for isStringSerializable keys improve serialization of AA to serialize if possible, skip otherwise --- source/vibe/data/json.d | 42 +++++++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/source/vibe/data/json.d b/source/vibe/data/json.d index 574ed08187..b9072e19f4 100644 --- a/source/vibe/data/json.d +++ b/source/vibe/data/json.d @@ -899,8 +899,16 @@ Json serializeToJson(T)(T value) return Json(ret); } else static if( isAssociativeArray!TU ){ Json[string] ret; - foreach( key, value; value ) - ret[to!string(key)] = serializeToJson(value); + alias KeyType!T TK; + foreach( key, value; value ) { + static if(is(TK == string)) { + ret[key] = serializeToJson(value); + } else static if(is(TK == enum)) { + ret[to!string(key)] = serializeToJson(value); + } else static if(isStringSerializable!(TK)) { + ret[key.toString()] = serializeToJson(value); + } + } return Json(ret); } else static if(isJsonSerializable!TU) { return value.toJson(); @@ -963,9 +971,18 @@ T deserializeJson(T)(Json src) return dst; } else static if( isAssociativeArray!T ){ alias typeof(T.init.values[0]) TV; - Unqual!TV[KeyType!T] dst; - foreach( string key, value; src ) - dst[to!(KeyType!T)(key)] = deserializeJson!(Unqual!TV)(value); + alias KeyType!T TK; + Unqual!TV[TK] dst; + foreach( string key, value; src ) { + static if(is(TK == string)) { + dst[key] = deserializeJson!(Unqual!TV)(value); + } else static if(is(TK == enum)) { + dst[to!(TK)(key)] = deserializeJson!(Unqual!TV)(value); + } else static if(isStringSerializable!TK) { + auto dsk = TK.fromString(key); + dst[dsk] = deserializeJson!(Unqual!TV)(value); + } + } return dst; } else static if (isJsonSerializable!T) { return T.fromJson(src); @@ -1058,12 +1075,15 @@ unittest { } unittest { - enum Color { Red, Green, Blue } - { + static struct C { int value; static C fromString(string val) { return C(val.to!int); } string toString() const { return value.to!string; } } + enum Color { Red, Green, Blue } + { static class T { string[Color] enumIndexedMap; + string[C] stringableIndexedMap; this() { enumIndexedMap = [ Color.Red : "magenta", Color.Blue : "deep blue" ]; + stringableIndexedMap = [ C(42) : "forty-two" ]; } } @@ -1072,19 +1092,21 @@ unittest { T other; deserializeJson(other, serializeToJson(original)); assert(serializeToJson(other) == serializeToJson(original)); - } - { + } + { static struct S { string[Color] enumIndexedMap; + string[C] stringableIndexedMap; } S *original = new S; original.enumIndexedMap = [ Color.Red : "magenta", Color.Blue : "deep blue" ]; original.enumIndexedMap[Color.Green] = "olive"; + original.stringableIndexedMap = [ C(42) : "forty-two" ]; S other; deserializeJson(other, serializeToJson(original)); assert(serializeToJson(other) == serializeToJson(original)); - } + } } /** From ed4f0ba0f78e59a00bc783a89e37fea05b446953 Mon Sep 17 00:00:00 2001 From: Daniel Davidson Date: Thu, 3 Oct 2013 11:19:19 -0500 Subject: [PATCH 3/3] fixed whitespace issue --- source/vibe/data/json.d | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/source/vibe/data/json.d b/source/vibe/data/json.d index b9072e19f4..32a0b5fc51 100644 --- a/source/vibe/data/json.d +++ b/source/vibe/data/json.d @@ -899,16 +899,16 @@ Json serializeToJson(T)(T value) return Json(ret); } else static if( isAssociativeArray!TU ){ Json[string] ret; - alias KeyType!T TK; + alias KeyType!T TK; foreach( key, value; value ) { - static if(is(TK == string)) { - ret[key] = serializeToJson(value); - } else static if(is(TK == enum)) { - ret[to!string(key)] = serializeToJson(value); - } else static if(isStringSerializable!(TK)) { - ret[key.toString()] = serializeToJson(value); - } - } + static if(is(TK == string)) { + ret[key] = serializeToJson(value); + } else static if(is(TK == enum)) { + ret[to!string(key)] = serializeToJson(value); + } else static if(isStringSerializable!(TK)) { + ret[key.toString()] = serializeToJson(value); + } + } return Json(ret); } else static if(isJsonSerializable!TU) { return value.toJson();