mirror of https://github.com/Hax-io/jstruct
Compare commits
34 Commits
|
@ -0,0 +1,32 @@
|
|||
# This workflow uses actions that are not certified by GitHub.
|
||||
# They are provided by a third-party and are governed by
|
||||
# separate terms of service, privacy policy, and support
|
||||
# documentation.
|
||||
name: D
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "master" ]
|
||||
pull_request:
|
||||
branches: [ "master" ]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: dlang-community/setup-dlang@4c99aa991ce7d19dd3064de0a4f2f6b2f152e2d7
|
||||
|
||||
- name: 'Build & Test'
|
||||
run: |
|
||||
# Build the project, with its main file included, without unittests
|
||||
dub build --compiler=$DC
|
||||
# Build and run tests, as defined by `unittest` configuration
|
||||
# In this mode, `mainSourceFile` is excluded and `version (unittest)` are included
|
||||
# See https://dub.pm/package-format-json.html#configurations
|
||||
dub test --compiler=$DC
|
49
README.md
49
README.md
|
@ -7,6 +7,8 @@ jstruct
|
|||
|
||||
----
|
||||
|
||||
[![D](https://github.com/Hax-io/jstruct/actions/workflows/d.yml/badge.svg)](https://github.com/Hax-io/jstruct/actions/workflows/d.yml) ![DUB](https://img.shields.io/dub/v/jstruct?color=%23c10000ff%20&style=flat-square) ![DUB](https://img.shields.io/dub/dt/jstruct?style=flat-square) ![DUB](https://img.shields.io/dub/l/jstruct?style=flat-square)
|
||||
|
||||
## Usage
|
||||
|
||||
### Serialization
|
||||
|
@ -20,6 +22,17 @@ struct Person
|
|||
public int age;
|
||||
public string[] list;
|
||||
public JSONValue extraJSON;
|
||||
public EnumType eType;
|
||||
}
|
||||
```
|
||||
|
||||
Our enum is defined as:
|
||||
|
||||
```d
|
||||
enum EnumType
|
||||
{
|
||||
DOG,
|
||||
CAT
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -32,6 +45,7 @@ p1.lastname = "Kildaire";
|
|||
p1.age = 23;
|
||||
p1.list = ["1", "2", "3"];
|
||||
p1.extraJSON = parseJSON(`{"item":1, "items":[1,2,3]}`);
|
||||
p1.eType = EnumType.CAT;
|
||||
```
|
||||
|
||||
Now, we make a call to `serializeRecord` as follows:
|
||||
|
@ -45,6 +59,7 @@ This returns the following JSON:
|
|||
```json
|
||||
{
|
||||
"age": 23,
|
||||
"eType": "CAT",
|
||||
"extraJSON": {
|
||||
"item": 1,
|
||||
"items": [
|
||||
|
@ -55,7 +70,11 @@ This returns the following JSON:
|
|||
},
|
||||
"firstname": "Tristan",
|
||||
"lastname": "Kildaire",
|
||||
"list": "[\"1\", \"2\", \"3\"]"
|
||||
"list": [
|
||||
"1",
|
||||
"2",
|
||||
"3"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -70,6 +89,12 @@ struct Person
|
|||
public int age;
|
||||
public bool isMale;
|
||||
public JSONValue obj;
|
||||
public int[] list;
|
||||
public bool[] list2;
|
||||
public float[] list3;
|
||||
public double[] list4;
|
||||
public string[] list5;
|
||||
public EnumType animal;
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -82,6 +107,12 @@ Now, let's say we were given the following JSON:
|
|||
"age": 23,
|
||||
"obj" : {"bruh":1},
|
||||
"isMale": true,
|
||||
"list": [1,2,3],
|
||||
"list2": [true, false],
|
||||
"list3": [1.5, 1.4],
|
||||
"list4": [1.5, 1.4],
|
||||
"list5": ["baba", "booey"],
|
||||
"animal": "CAT"
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -95,7 +126,12 @@ JSONValue json = parseJSON(`{
|
|||
"age": 23,
|
||||
"obj" : {"bruh":1},
|
||||
"isMale": true,
|
||||
"list": [1,2,3]
|
||||
"list": [1,2,3],
|
||||
"list2": [true, false],
|
||||
"list3": [1.5, 1.4],
|
||||
"list4": [1.5, 1.4],
|
||||
"list5": ["baba", "booey"],
|
||||
"animal": "CAT"
|
||||
}
|
||||
`);
|
||||
|
||||
|
@ -112,7 +148,7 @@ writeln(person):
|
|||
Which will output:
|
||||
|
||||
```
|
||||
Person("Tristan", "Kildaire", 23, true, {"bruh":1})
|
||||
Person("Tristan", "Kildaire", 23, true, {"bruh":1}, [1, 2, 3], [true, false], [1.5, 1.4], [1.5, 1.4], ["baba", "booey"], CAT)
|
||||
```
|
||||
|
||||
## Installing
|
||||
|
@ -128,10 +164,3 @@ And then in your D program import as follows:
|
|||
```d
|
||||
import jstruct;
|
||||
```
|
||||
|
||||
## Help wanted
|
||||
|
||||
There are some outstanding issues I want to be able to fix/have implemented, namely:
|
||||
|
||||
- [ ] Support for array serialization/deserialization - see issue #1
|
||||
- [ ] Support for custom types serialization/deserialization (think `enums` for example) - see issue #2
|
|
@ -1,20 +1,23 @@
|
|||
/**
|
||||
* Deserialization utilities
|
||||
*/
|
||||
module jstruct.deserializer;
|
||||
|
||||
import std.json;
|
||||
import jstruct.exceptions : SerializationError;
|
||||
|
||||
import std.traits : FieldTypeTuple, FieldNameTuple;
|
||||
import jstruct.exceptions : DeserializationError;
|
||||
import std.traits : FieldTypeTuple, FieldNameTuple, isArray, ForeachType, EnumMembers, fullyQualifiedName;;
|
||||
import std.conv : to;
|
||||
|
||||
/**
|
||||
* Deserializes the provided JSON into a struct of type RecordType
|
||||
*
|
||||
* Params:
|
||||
* jsonIn = the JSON to deserialize
|
||||
* Throws:
|
||||
* RemoteFieldMissing = if the field names in the provided RecordType
|
||||
* cannot be found within the prpvided JSONValue `jsonIn`.
|
||||
* Returns: an instance of RecordType
|
||||
*/
|
||||
* Deserializes the provided JSON into a struct of type RecordType
|
||||
*
|
||||
* Params:
|
||||
* jsonIn = the JSON to deserialize
|
||||
* Throws:
|
||||
* RemoteFieldMissing = if the field names in the provided RecordType
|
||||
* cannot be found within the prpvided JSONValue `jsonIn`.
|
||||
* Returns: an instance of RecordType
|
||||
*/
|
||||
public RecordType fromJSON(RecordType)(JSONValue jsonIn)
|
||||
{
|
||||
RecordType record;
|
||||
|
@ -42,39 +45,39 @@ public RecordType fromJSON(RecordType)(JSONValue jsonIn)
|
|||
|
||||
try
|
||||
{
|
||||
static if(__traits(isSame, mixin(structTypes[cnt]), byte))
|
||||
static if(__traits(isSame, structTypes[cnt], byte))
|
||||
{
|
||||
mixin("record."~structNames[cnt]) = cast(byte)jsonIn[structNames[cnt]].integer();
|
||||
}
|
||||
else static if(__traits(isSame, mixin(structTypes[cnt]), ubyte))
|
||||
else static if(__traits(isSame, structTypes[cnt], ubyte))
|
||||
{
|
||||
mixin("record."~structNames[cnt]) = cast(ubyte)jsonIn[structNames[cnt]].uinteger();
|
||||
}
|
||||
else static if(__traits(isSame, mixin(structTypes[cnt]), short))
|
||||
else static if(__traits(isSame, structTypes[cnt], short))
|
||||
{
|
||||
mixin("record."~structNames[cnt]) = cast(short)jsonIn[structNames[cnt]].integer();
|
||||
}
|
||||
else static if(__traits(isSame, mixin(structTypes[cnt]), ushort))
|
||||
else static if(__traits(isSame, structTypes[cnt], ushort))
|
||||
{
|
||||
mixin("record."~structNames[cnt]) = cast(ushort)jsonIn[structNames[cnt]].uinteger();
|
||||
}
|
||||
else static if(__traits(isSame, mixin(structTypes[cnt]), int))
|
||||
else static if(__traits(isSame, structTypes[cnt], int))
|
||||
{
|
||||
mixin("record."~structNames[cnt]) = cast(int)jsonIn[structNames[cnt]].integer();
|
||||
}
|
||||
else static if(__traits(isSame, mixin(structTypes[cnt]), uint))
|
||||
else static if(__traits(isSame, structTypes[cnt], uint))
|
||||
{
|
||||
mixin("record."~structNames[cnt]) = cast(uint)jsonIn[structNames[cnt]].uinteger();
|
||||
}
|
||||
else static if(__traits(isSame, mixin(structTypes[cnt]), ulong))
|
||||
else static if(__traits(isSame, structTypes[cnt], ulong))
|
||||
{
|
||||
mixin("record."~structNames[cnt]) = cast(ulong)jsonIn[structNames[cnt]].uinteger();
|
||||
}
|
||||
else static if(__traits(isSame, mixin(structTypes[cnt]), long))
|
||||
else static if(__traits(isSame, structTypes[cnt], long))
|
||||
{
|
||||
mixin("record."~structNames[cnt]) = cast(long)jsonIn[structNames[cnt]].integer();
|
||||
}
|
||||
else static if(__traits(isSame, mixin(structTypes[cnt]), string))
|
||||
else static if(__traits(isSame, structTypes[cnt], string))
|
||||
{
|
||||
mixin("record."~structNames[cnt]) = jsonIn[structNames[cnt]].str();
|
||||
|
||||
|
@ -83,7 +86,7 @@ public RecordType fromJSON(RecordType)(JSONValue jsonIn)
|
|||
pragma(msg,"record."~structNames[cnt]);
|
||||
}
|
||||
}
|
||||
else static if(__traits(isSame, mixin(structTypes[cnt]), JSONValue))
|
||||
else static if(__traits(isSame, structTypes[cnt], JSONValue))
|
||||
{
|
||||
mixin("record."~structNames[cnt]) = jsonIn[structNames[cnt]];
|
||||
|
||||
|
@ -92,7 +95,7 @@ public RecordType fromJSON(RecordType)(JSONValue jsonIn)
|
|||
pragma(msg,"record."~structNames[cnt]);
|
||||
}
|
||||
}
|
||||
else static if(__traits(isSame, mixin(structTypes[cnt]), bool))
|
||||
else static if(__traits(isSame, structTypes[cnt], bool))
|
||||
{
|
||||
mixin("record."~structNames[cnt]) = jsonIn[structNames[cnt]].boolean();
|
||||
|
||||
|
@ -101,16 +104,103 @@ public RecordType fromJSON(RecordType)(JSONValue jsonIn)
|
|||
pragma(msg,"record."~structNames[cnt]);
|
||||
}
|
||||
}
|
||||
//FIXME: Not sure how to get array support going, very new to meta programming
|
||||
else static if(__traits(isSame, mixin(structTypes[cnt]), mixin(structTypes[cnt])[]))
|
||||
else static if(isArray!(structTypes[cnt]))
|
||||
{
|
||||
mixin("record."~structNames[cnt]) = jsonIn[structNames[cnt]].boolean();
|
||||
alias recordArrayComponent = mixin("record."~structNames[cnt]);
|
||||
|
||||
JSONValue[] jsonArray = jsonIn[structNames[cnt]].array();
|
||||
|
||||
for(ulong i = 0; i < jsonArray.length; i++)
|
||||
{
|
||||
JSONValue jsonVal = jsonArray[i];
|
||||
|
||||
static if(__traits(isSame, ForeachType!(structTypes[cnt]), byte))
|
||||
{
|
||||
mixin("record."~structNames[cnt])~= cast(byte)jsonVal.integer();
|
||||
}
|
||||
else static if(__traits(isSame, ForeachType!(structTypes[cnt]), ubyte))
|
||||
{
|
||||
mixin("record."~structNames[cnt])~= cast(ubyte)jsonVal.uinteger();
|
||||
}
|
||||
static if(__traits(isSame, ForeachType!(structTypes[cnt]), short))
|
||||
{
|
||||
mixin("record."~structNames[cnt])~= cast(short)jsonVal.integer();
|
||||
}
|
||||
else static if(__traits(isSame, ForeachType!(structTypes[cnt]), ushort))
|
||||
{
|
||||
mixin("record."~structNames[cnt])~= cast(ushort)jsonVal.uinteger();
|
||||
}
|
||||
static if(__traits(isSame, ForeachType!(structTypes[cnt]), int))
|
||||
{
|
||||
mixin("record."~structNames[cnt])~= cast(int)jsonVal.integer();
|
||||
}
|
||||
else static if(__traits(isSame, ForeachType!(structTypes[cnt]), uint))
|
||||
{
|
||||
mixin("record."~structNames[cnt])~= cast(uint)jsonVal.uinteger();
|
||||
}
|
||||
static if(__traits(isSame, ForeachType!(structTypes[cnt]), long))
|
||||
{
|
||||
mixin("record."~structNames[cnt])~= cast(long)jsonVal.integer();
|
||||
}
|
||||
else static if(__traits(isSame, ForeachType!(structTypes[cnt]), ulong))
|
||||
{
|
||||
mixin("record."~structNames[cnt])~= cast(ulong)jsonVal.uinteger();
|
||||
}
|
||||
else static if(__traits(isSame, ForeachType!(structTypes[cnt]), bool))
|
||||
{
|
||||
mixin("record."~structNames[cnt])~= jsonVal.boolean();
|
||||
}
|
||||
else static if(__traits(isSame, ForeachType!(structTypes[cnt]), float))
|
||||
{
|
||||
mixin("record."~structNames[cnt])~= cast(float)jsonVal.floating();
|
||||
}
|
||||
else static if(__traits(isSame, ForeachType!(structTypes[cnt]), double))
|
||||
{
|
||||
mixin("record."~structNames[cnt])~= cast(double)jsonVal.floating();
|
||||
}
|
||||
else static if(__traits(isSame, ForeachType!(structTypes[cnt]), string))
|
||||
{
|
||||
mixin("record."~structNames[cnt])~= jsonVal.str();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
// mixin("record."~structNames[cnt]) = jsonIn[structNames[cnt]].array();
|
||||
|
||||
debug(dbg)
|
||||
{
|
||||
pragma(msg,"record."~structNames[cnt]);
|
||||
}
|
||||
}
|
||||
else static if(is(structTypes[cnt] == enum))
|
||||
{
|
||||
string enumChoice = jsonIn[structNames[cnt]].str();
|
||||
|
||||
alias members = EnumMembers!(structTypes[cnt]);
|
||||
|
||||
version(dbg)
|
||||
{
|
||||
import std.stdio : writeln;
|
||||
}
|
||||
|
||||
static foreach(member; members)
|
||||
{
|
||||
version(dbg)
|
||||
{
|
||||
writeln(member);
|
||||
writeln(fullyQualifiedName!(member));
|
||||
writeln(__traits(identifier, member));
|
||||
}
|
||||
|
||||
if(__traits(identifier, member) == enumChoice)
|
||||
{
|
||||
mixin("record."~structNames[cnt]) = member;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// throw new
|
||||
|
@ -118,22 +208,33 @@ public RecordType fromJSON(RecordType)(JSONValue jsonIn)
|
|||
debug(dbg)
|
||||
{
|
||||
pragma(msg, "Unknown type for de-serialization");
|
||||
|
||||
pragma(msg, is(structTypes[cnt] == enum));
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(JSONException e)
|
||||
{
|
||||
throw new SerializationError();
|
||||
throw new DeserializationError();
|
||||
}
|
||||
}
|
||||
|
||||
return record;
|
||||
}
|
||||
|
||||
/**
|
||||
* Example deserialization of JSON
|
||||
* to our `Person` struct
|
||||
*/
|
||||
unittest
|
||||
{
|
||||
import std.string : cmp;
|
||||
import std.stdio : writeln;
|
||||
enum EnumType
|
||||
{
|
||||
DOG,
|
||||
CAT
|
||||
}
|
||||
|
||||
struct Person
|
||||
{
|
||||
|
@ -142,6 +243,11 @@ unittest
|
|||
public bool isMale;
|
||||
public JSONValue obj;
|
||||
public int[] list;
|
||||
public bool[] list2;
|
||||
public float[] list3;
|
||||
public double[] list4;
|
||||
public string[] list5;
|
||||
public EnumType animal;
|
||||
}
|
||||
|
||||
JSONValue json = parseJSON(`{
|
||||
|
@ -150,7 +256,12 @@ unittest
|
|||
"age": 23,
|
||||
"obj" : {"bruh":1},
|
||||
"isMale": true,
|
||||
"list": [1,2,3]
|
||||
"list": [1,2,3],
|
||||
"list2": [true, false],
|
||||
"list3": [1.5, 1.4],
|
||||
"list4": [1.5, 1.4],
|
||||
"list5": ["baba", "booey"],
|
||||
"animal": "CAT"
|
||||
}
|
||||
`);
|
||||
|
||||
|
@ -158,7 +269,7 @@ unittest
|
|||
|
||||
debug(dbg)
|
||||
{
|
||||
writeln(person);
|
||||
writeln("Deserialized as: ", person);
|
||||
}
|
||||
|
||||
assert(cmp(person.firstname, "Tristan") == 0);
|
||||
|
@ -166,14 +277,30 @@ unittest
|
|||
assert(person.age == 23);
|
||||
assert(person.isMale == true);
|
||||
assert(person.obj["bruh"].integer() == 1);
|
||||
//TODO: list test case
|
||||
assert(person.list == [1,2,3]);
|
||||
assert(person.list2 == [true, false]);
|
||||
assert(person.list3 == [1.5F, 1.4F]);
|
||||
assert(person.list4 == [1.5, 1.4]);
|
||||
assert(person.list5 == ["baba", "booey"]);
|
||||
assert(person.animal == EnumType.CAT);
|
||||
|
||||
}
|
||||
|
||||
unittest
|
||||
version(unittest)
|
||||
{
|
||||
import std.string : cmp;
|
||||
import std.stdio : writeln;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Another example deserialization of JSON
|
||||
* to our `Person` struct but here there
|
||||
* is a problem with deserialization as
|
||||
* there is a missing field `isMale`
|
||||
* in the provided JSON
|
||||
*/
|
||||
unittest
|
||||
{
|
||||
struct Person
|
||||
{
|
||||
public string firstname, lastname;
|
||||
|
@ -181,6 +308,7 @@ unittest
|
|||
public bool isMale;
|
||||
public JSONValue obj;
|
||||
public int[] list;
|
||||
|
||||
}
|
||||
|
||||
JSONValue json = parseJSON(`{
|
||||
|
@ -197,9 +325,47 @@ unittest
|
|||
Person person = fromJSON!(Person)(json);
|
||||
assert(false);
|
||||
}
|
||||
catch(SerializationError)
|
||||
catch(DeserializationError)
|
||||
{
|
||||
assert(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
unittest
|
||||
{
|
||||
enum EnumType
|
||||
{
|
||||
DOG,
|
||||
CAT
|
||||
}
|
||||
|
||||
struct Person
|
||||
{
|
||||
public string firstname, lastname;
|
||||
|
||||
|
||||
public EnumType animal;
|
||||
|
||||
}
|
||||
|
||||
JSONValue json = parseJSON(`{
|
||||
"firstname" : "Tristan",
|
||||
"lastname": "Kildaire",
|
||||
"animal" : "CAT"
|
||||
}
|
||||
`);
|
||||
|
||||
try
|
||||
{
|
||||
Person person = fromJSON!(Person)(json);
|
||||
writeln(person);
|
||||
assert(true);
|
||||
}
|
||||
catch(DeserializationError)
|
||||
{
|
||||
assert(false);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,5 +1,11 @@
|
|||
/**
|
||||
* Exception types
|
||||
*/
|
||||
module jstruct.exceptions;
|
||||
|
||||
/**
|
||||
* General exception type
|
||||
*/
|
||||
public abstract class JStructException : Exception
|
||||
{
|
||||
this(string msg)
|
||||
|
@ -8,10 +14,24 @@ public abstract class JStructException : Exception
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Error on serialization
|
||||
*/
|
||||
public final class SerializationError : JStructException
|
||||
{
|
||||
this()
|
||||
{
|
||||
super("Errro serializing");
|
||||
super("Error serializing");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Error on deserialization
|
||||
*/
|
||||
public final class DeserializationError : JStructException
|
||||
{
|
||||
this()
|
||||
{
|
||||
super("Error deserializing");
|
||||
}
|
||||
}
|
|
@ -1,4 +1,19 @@
|
|||
/**
|
||||
* Struct JSON serializer/deserializer
|
||||
*/
|
||||
module jstruct;
|
||||
|
||||
/**
|
||||
* Serialization utilities
|
||||
*/
|
||||
public import jstruct.serializer;
|
||||
public import jstruct.deserializer;
|
||||
|
||||
/**
|
||||
* Deserialization utilities
|
||||
*/
|
||||
public import jstruct.deserializer;
|
||||
|
||||
/**
|
||||
* Exception types
|
||||
*/
|
||||
public import jstruct.exceptions;
|
|
@ -1,9 +1,20 @@
|
|||
/**
|
||||
* Serialization utilities
|
||||
*/
|
||||
module jstruct.serializer;
|
||||
|
||||
import std.json;
|
||||
import std.conv : to;
|
||||
import std.traits : FieldTypeTuple, FieldNameTuple;
|
||||
import std.traits : isArray;
|
||||
|
||||
/**
|
||||
* Serializes the provided record into JSON
|
||||
*
|
||||
* Params:
|
||||
* record = the record to serialize into
|
||||
* Returns: A `JSONValue` containing the serialized record
|
||||
*/
|
||||
public JSONValue serializeRecord(RecordType)(RecordType record)
|
||||
{
|
||||
// Final JSON to submit
|
||||
|
@ -23,32 +34,35 @@ public JSONValue serializeRecord(RecordType)(RecordType record)
|
|||
// pragma(msg, structValues[cnt]);
|
||||
}
|
||||
|
||||
|
||||
static if(__traits(isSame, mixin(structTypes[cnt]), int))
|
||||
static if(__traits(isSame, structTypes[cnt], int))
|
||||
{
|
||||
builtJSON[structNames[cnt]] = structValues[cnt];
|
||||
}
|
||||
else static if(__traits(isSame, mixin(structTypes[cnt]), uint))
|
||||
else static if(__traits(isSame, structTypes[cnt], uint))
|
||||
{
|
||||
builtJSON[structNames[cnt]] = structValues[cnt];
|
||||
}
|
||||
else static if(__traits(isSame, mixin(structTypes[cnt]), ulong))
|
||||
else static if(__traits(isSame, structTypes[cnt], ulong))
|
||||
{
|
||||
builtJSON[structNames[cnt]] = structValues[cnt];
|
||||
}
|
||||
else static if(__traits(isSame, mixin(structTypes[cnt]), long))
|
||||
else static if(__traits(isSame, structTypes[cnt], long))
|
||||
{
|
||||
builtJSON[structNames[cnt]] = structValues[cnt];
|
||||
}
|
||||
else static if(__traits(isSame, mixin(structTypes[cnt]), string))
|
||||
else static if(__traits(isSame, structTypes[cnt], string))
|
||||
{
|
||||
builtJSON[structNames[cnt]] = structValues[cnt];
|
||||
}
|
||||
else static if(__traits(isSame, mixin(structTypes[cnt]), JSONValue))
|
||||
else static if(__traits(isSame, structTypes[cnt], JSONValue))
|
||||
{
|
||||
builtJSON[structNames[cnt]] = structValues[cnt];
|
||||
}
|
||||
else static if(__traits(isSame, mixin(structTypes[cnt]), bool))
|
||||
else static if(__traits(isSame, structTypes[cnt], bool))
|
||||
{
|
||||
builtJSON[structNames[cnt]] = structValues[cnt];
|
||||
}
|
||||
else static if(isArray!(structTypes[cnt]))
|
||||
{
|
||||
builtJSON[structNames[cnt]] = structValues[cnt];
|
||||
}
|
||||
|
@ -67,17 +81,27 @@ public JSONValue serializeRecord(RecordType)(RecordType record)
|
|||
}
|
||||
|
||||
// Test serialization of a struct to JSON
|
||||
private enum EnumType
|
||||
{
|
||||
DOG,
|
||||
CAT
|
||||
}
|
||||
unittest
|
||||
|
||||
|
||||
version(unittest)
|
||||
{
|
||||
import std.algorithm.searching : canFind;
|
||||
import std.string : cmp;
|
||||
import std.stdio : writeln;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Example serialization of our struct
|
||||
* `Person` to JSON
|
||||
*/
|
||||
unittest
|
||||
{
|
||||
enum EnumType
|
||||
{
|
||||
DOG,
|
||||
CAT
|
||||
}
|
||||
|
||||
struct Person
|
||||
{
|
||||
public string firstname, lastname;
|
||||
|
@ -102,6 +126,14 @@ unittest
|
|||
assert(canFind(keys, "lastname") && cmp(serialized["lastname"].str(), "Kildaire") == 0);
|
||||
assert(canFind(keys, "age") && serialized["age"].integer() == 23);
|
||||
|
||||
assert(canFind(keys, "list"));
|
||||
JSONValue[] elems = serialized["list"].array();
|
||||
for(ulong i = 0; i < elems.length; i++)
|
||||
{
|
||||
string curElem = elems[i].str();
|
||||
assert(curElem == p1.list[i]);
|
||||
}
|
||||
|
||||
debug(dbg)
|
||||
{
|
||||
writeln(serialized.toPrettyString());
|
||||
|
|
Loading…
Reference in New Issue