diff --git a/source/libpb/deserialization.d b/source/libpb/deserialization.d index cf8fdc2..31e90f5 100644 --- a/source/libpb/deserialization.d +++ b/source/libpb/deserialization.d @@ -1,11 +1,28 @@ module libpb.deserialization; import std.json; +import libpb.exceptions : RemoteFieldMissing; - +/** + * T + * + * Params: + * RecordType = type of the struct to construct + */ mixin template T(RecordType) { import std.traits : FieldTypeTuple, FieldNameTuple; + + /** + * 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(JSONValue jsonIn) { RecordType record; @@ -24,83 +41,94 @@ mixin template T(RecordType) // pragma(msg, structValues[cnt]); } - static if(__traits(isSame, mixin(structTypes[cnt]), byte)) - { - mixin("record."~structNames[cnt]) = cast(byte)jsonIn[structNames[cnt]].integer(); - } - else static if(__traits(isSame, mixin(structTypes[cnt]), ubyte)) - { - mixin("record."~structNames[cnt]) = cast(ubyte)jsonIn[structNames[cnt]].uinteger(); - } - else static if(__traits(isSame, mixin(structTypes[cnt]), short)) - { - mixin("record."~structNames[cnt]) = cast(short)jsonIn[structNames[cnt]].integer(); - } - else static if(__traits(isSame, mixin(structTypes[cnt]), ushort)) - { - mixin("record."~structNames[cnt]) = cast(ushort)jsonIn[structNames[cnt]].uinteger(); - } - else static if(__traits(isSame, mixin(structTypes[cnt]), int)) - { - mixin("record."~structNames[cnt]) = cast(int)jsonIn[structNames[cnt]].integer(); - } - else static if(__traits(isSame, mixin(structTypes[cnt]), uint)) - { - mixin("record."~structNames[cnt]) = cast(uint)jsonIn[structNames[cnt]].uinteger(); - } - else static if(__traits(isSame, mixin(structTypes[cnt]), ulong)) - { - mixin("record."~structNames[cnt]) = cast(ulong)jsonIn[structNames[cnt]].uinteger(); - } - else static if(__traits(isSame, mixin(structTypes[cnt]), long)) - { - mixin("record."~structNames[cnt]) = cast(long)jsonIn[structNames[cnt]].integer(); - } - else static if(__traits(isSame, mixin(structTypes[cnt]), string)) - { - mixin("record."~structNames[cnt]) = jsonIn[structNames[cnt]].str(); + pragma(msg, "Bruh type"); + pragma(msg, structTypes[cnt]); + // pragma(msg, __traits(identifier, mixin(structTypes[cnt]))); - debug(dbg) - { - pragma(msg,"record."~structNames[cnt]); - } - } - else static if(__traits(isSame, mixin(structTypes[cnt]), JSONValue)) + try { - mixin("record."~structNames[cnt]) = jsonIn[structNames[cnt]]; + static if(__traits(isSame, mixin(structTypes[cnt]), byte)) + { + mixin("record."~structNames[cnt]) = cast(byte)jsonIn[structNames[cnt]].integer(); + } + else static if(__traits(isSame, mixin(structTypes[cnt]), ubyte)) + { + mixin("record."~structNames[cnt]) = cast(ubyte)jsonIn[structNames[cnt]].uinteger(); + } + else static if(__traits(isSame, mixin(structTypes[cnt]), short)) + { + mixin("record."~structNames[cnt]) = cast(short)jsonIn[structNames[cnt]].integer(); + } + else static if(__traits(isSame, mixin(structTypes[cnt]), ushort)) + { + mixin("record."~structNames[cnt]) = cast(ushort)jsonIn[structNames[cnt]].uinteger(); + } + else static if(__traits(isSame, mixin(structTypes[cnt]), int)) + { + mixin("record."~structNames[cnt]) = cast(int)jsonIn[structNames[cnt]].integer(); + } + else static if(__traits(isSame, mixin(structTypes[cnt]), uint)) + { + mixin("record."~structNames[cnt]) = cast(uint)jsonIn[structNames[cnt]].uinteger(); + } + else static if(__traits(isSame, mixin(structTypes[cnt]), ulong)) + { + mixin("record."~structNames[cnt]) = cast(ulong)jsonIn[structNames[cnt]].uinteger(); + } + else static if(__traits(isSame, mixin(structTypes[cnt]), long)) + { + mixin("record."~structNames[cnt]) = cast(long)jsonIn[structNames[cnt]].integer(); + } + else static if(__traits(isSame, mixin(structTypes[cnt]), string)) + { + mixin("record."~structNames[cnt]) = jsonIn[structNames[cnt]].str(); - debug(dbg) - { - pragma(msg,"record."~structNames[cnt]); + debug(dbg) + { + pragma(msg,"record."~structNames[cnt]); + } } - } - else static if(__traits(isSame, mixin(structTypes[cnt]), bool)) - { - mixin("record."~structNames[cnt]) = jsonIn[structNames[cnt]].boolean(); + else static if(__traits(isSame, mixin(structTypes[cnt]), JSONValue)) + { + mixin("record."~structNames[cnt]) = jsonIn[structNames[cnt]]; - debug(dbg) - { - pragma(msg,"record."~structNames[cnt]); + debug(dbg) + { + 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])[])) - { - mixin("record."~structNames[cnt]) = jsonIn[structNames[cnt]].boolean(); + else static if(__traits(isSame, mixin(structTypes[cnt]), bool)) + { + mixin("record."~structNames[cnt]) = jsonIn[structNames[cnt]].boolean(); - debug(dbg) + debug(dbg) + { + 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])[])) { - pragma(msg,"record."~structNames[cnt]); + mixin("record."~structNames[cnt]) = jsonIn[structNames[cnt]].boolean(); + + debug(dbg) + { + pragma(msg,"record."~structNames[cnt]); + } + } + else + { + // throw new + //TODO: Throw error + debug(dbg) + { + pragma(msg, "Unknown type for de-serialization"); + } } } - else + catch(JSONException e) { - // throw new - //TODO: Throw error - debug(dbg) - { - pragma(msg, "Unknown type for de-serialization"); - } + throw new RemoteFieldMissing(); } } @@ -147,3 +175,39 @@ unittest assert(person.obj["bruh"].integer() == 1); //TODO: list test case } + +unittest +{ + import std.string : cmp; + import std.stdio : writeln; + + struct Person + { + public string firstname, lastname; + public int age; + public bool isMale; + public JSONValue obj; + public int[] list; + } + + JSONValue json = parseJSON(`{ +"firstname" : "Tristan", +"lastname": "Kildaire", +"age": 23, +"obj" : {"bruh":1}, +"list": [1,2,3] +} +`); + + mixin T!(Person); + try + { + Person person = fromJSON(json); + assert(false); + } + catch(RemoteFieldMissing) + { + assert(true); + } + +} \ No newline at end of file diff --git a/source/libpb/exceptions.d b/source/libpb/exceptions.d index e1feebe..6744988 100644 --- a/source/libpb/exceptions.d +++ b/source/libpb/exceptions.d @@ -61,3 +61,12 @@ public final class PocketBaseParsingException : PBException { } + + +public final class RemoteFieldMissing : PBException +{ + this() + { + + } +} \ No newline at end of file