1 module jsonserialized.serialization; 2 3 import std.conv; 4 import stdx.data.json; 5 import std.traits; 6 7 @safe: 8 9 /// Convert the specified array into a JSONValue. 10 pure JSONValue serializeToJSONValue(T)(in ref T array) if (isArray!T) { 11 alias ElementType = ForeachType!T; 12 13 JSONValue[] values; 14 15 // Iterate each item in the array and add them to the array of JSON values 16 foreach(item; array) { 17 static if (is(ElementType == struct)) { 18 // This item is a struct 19 values ~= item.serializeToJSONValue(); 20 } 21 else static if (is(ElementType == class)) { 22 // This item is a class - serialize it unless it is null 23 if (item !is null) { 24 values ~= item.serializeToJSONValue(); 25 } 26 } 27 else static if (isSomeString!ElementType) { 28 values ~= JSONValue(item.to!string); 29 } 30 else static if (isArray!ElementType) { 31 // An array of arrays. Recursion time! 32 values ~= item.serializeToJSONValue(); 33 } 34 else { 35 values ~= JSONValue(item); 36 } 37 } 38 39 return JSONValue(values); 40 } 41 42 /// Convert the specified associative array into a JSONValue. 43 pure JSONValue serializeToJSONValue(T)(in ref T associativeArray) if (isAssociativeArray!T) { 44 alias VType = ValueType!T; 45 46 JSONValue[string] items; 47 48 // Iterate each item in the associative array 49 foreach(key, value; associativeArray) { 50 // JSON keys have to be strings, so convert every key to a string 51 auto stringKey = key.to!string; 52 53 static if (is(VType == struct)) { 54 // The value type is struct 55 items[stringKey] = value.serializeToJSONValue(); 56 } 57 else static if (is(VType == class)) { 58 // The value is a class - serialize it unless it is null 59 if (value !is null) { 60 items[stringKey] = value.serializeToJSONValue(); 61 } 62 } 63 else static if (isAssociativeArray!VType) { 64 /* The associative array's value type is another associative array type. 65 It's recursion time. */ 66 items[stringKey] = value.serializeToJSONValue(); 67 } 68 else static if (isSomeString!VType) { 69 items[stringKey] = JSONValue(value.to!string); 70 } 71 else { 72 items[stringKey] = JSONValue(value); 73 } 74 } 75 76 return JSONValue(items); 77 } 78 79 /// Convert the specified struct or class into a JSONValue. 80 pure JSONValue serializeToJSONValue(T)(in ref T obj) if (is(T == struct) || is(T == class)) { 81 enum fieldNames = FieldNameTuple!T; 82 83 JSONValue[string] jsonValues; 84 85 foreach(fieldName; fieldNames) { 86 auto field = __traits(getMember, obj, fieldName); 87 alias FieldType = typeof(field); 88 89 static if (is(FieldType == struct)) { 90 // This field is a struct - recurse into it 91 jsonValues[fieldName] = field.serializeToJSONValue(); 92 } 93 else static if (is(FieldType == class)) { 94 // This field is a class - recurse into it unless it is null 95 if (field !is null) { 96 jsonValues[fieldName] = field.serializeToJSONValue(); 97 } 98 } 99 else static if (isSomeString!FieldType) { 100 // Because JSONValue only seems to work with string strings (and not char[], etc), convert all string types to string 101 jsonValues[fieldName] = JSONValue(field.to!string); 102 } 103 else static if (isArray!FieldType) { 104 // Field is an array 105 jsonValues[fieldName] = field.serializeToJSONValue(); 106 } 107 else static if (isAssociativeArray!FieldType) { 108 // Field is an associative array 109 jsonValues[fieldName] = field.serializeToJSONValue(); 110 } 111 else { 112 jsonValues[fieldName] = JSONValue(field); 113 } 114 } 115 116 return JSONValue(jsonValues); 117 }