- Moved back to more clean templating method (for now till a fix can be found for the type lookups for issue #7)

This commit is contained in:
Tristan B. Velloza Kildaire 2023-01-09 10:28:56 +02:00
parent c89d6bd8b6
commit 4fc4242c1e
2 changed files with 120 additions and 134 deletions

View File

@ -3,137 +3,131 @@ module libpb.deserialization;
import std.json; import std.json;
import libpb.exceptions : RemoteFieldMissing; import libpb.exceptions : RemoteFieldMissing;
import std.traits : FieldTypeTuple, FieldNameTuple;
/** /**
* T * Deserializes the provided JSON into a struct of type RecordType
* *
* Params: * Params:
* RecordType = type of the struct to construct * jsonIn = the JSON to deserialize
*/ * Throws:
mixin template T(RecordType) * 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)
{ {
import std.traits : FieldTypeTuple, FieldNameTuple; RecordType record;
/** // Alias as to only expand later when used in compile-time
* Deserializes the provided JSON into a struct of type RecordType alias structTypes = FieldTypeTuple!(RecordType);
* alias structNames = FieldNameTuple!(RecordType);
* Params: alias structValues = record.tupleof;
* jsonIn = the JSON to deserialize
* Throws: static foreach(cnt; 0..structTypes.length)
* 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; debug(dbg)
// Alias as to only expand later when used in compile-time
alias structTypes = FieldTypeTuple!(RecordType);
alias structNames = FieldNameTuple!(RecordType);
alias structValues = record.tupleof;
static foreach(cnt; 0..structTypes.length)
{ {
debug(dbg) pragma(msg, structTypes[cnt]);
{ pragma(msg, structNames[cnt]);
pragma(msg, structTypes[cnt]); // pragma(msg, structValues[cnt]);
pragma(msg, structNames[cnt]); }
// pragma(msg, structValues[cnt]);
}
debug(dbg)
{
pragma(msg, "Bruh type"); pragma(msg, "Bruh type");
pragma(msg, structTypes[cnt]); pragma(msg, structTypes[cnt]);
// pragma(msg, __traits(identifier, mixin(structTypes[cnt]))); // pragma(msg, __traits(identifier, mixin(structTypes[cnt])));
try
{
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]);
}
}
else static if(__traits(isSame, mixin(structTypes[cnt]), JSONValue))
{
mixin("record."~structNames[cnt]) = jsonIn[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();
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();
debug(dbg)
{
pragma(msg,"record."~structNames[cnt]);
}
}
else
{
// throw new
//TODO: Throw error
debug(dbg)
{
pragma(msg, "Unknown type for de-serialization");
}
}
}
catch(JSONException e)
{
throw new RemoteFieldMissing();
}
} }
return record; try
{
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]);
}
}
else static if(__traits(isSame, mixin(structTypes[cnt]), JSONValue))
{
mixin("record."~structNames[cnt]) = jsonIn[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();
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();
debug(dbg)
{
pragma(msg,"record."~structNames[cnt]);
}
}
else
{
// throw new
//TODO: Throw error
debug(dbg)
{
pragma(msg, "Unknown type for de-serialization");
}
}
}
catch(JSONException e)
{
throw new RemoteFieldMissing();
}
} }
return record;
} }
unittest unittest
@ -160,8 +154,7 @@ unittest
} }
`); `);
mixin T!(Person); Person person = fromJSON!(Person)(json);
Person person = fromJSON(json);
debug(dbg) debug(dbg)
{ {
@ -199,10 +192,9 @@ unittest
} }
`); `);
mixin T!(Person);
try try
{ {
Person person = fromJSON(json); Person person = fromJSON!(Person)(json);
assert(false); assert(false);
} }
catch(RemoteFieldMissing) catch(RemoteFieldMissing)

View File

@ -158,8 +158,7 @@ public class PocketBase
} }
} }
mixin T!(RecordType); recordsOut ~= fromJSON!(RecordType)(returnedItem);
recordsOut ~= fromJSON(returnedItem);
} }
return recordsOut; return recordsOut;
@ -269,8 +268,7 @@ public class PocketBase
responseJSON["passwordConfirm"] = ""; responseJSON["passwordConfirm"] = "";
} }
mixin T!(RecordType); recordOut = fromJSON!(RecordType)(responseJSON);
recordOut = fromJSON(responseJSON);
return recordOut; return recordOut;
} }
@ -350,9 +348,7 @@ public class PocketBase
recordResponse["email"] = ""; recordResponse["email"] = "";
} }
recordOut = fromJSON!(RecordType)(recordResponse);
mixin T!(RecordType);
recordOut = fromJSON(recordResponse);
// Store the token // Store the token
token = responseJSON["token"].str(); token = responseJSON["token"].str();
@ -451,8 +447,7 @@ public class PocketBase
} }
} }
mixin T!(RecordType); recordOut = fromJSON!(RecordType)(responseJSON);
recordOut = fromJSON(responseJSON);
return recordOut; return recordOut;
} }
@ -557,8 +552,7 @@ public class PocketBase
} }
} }
mixin T!(RecordType); recordOut = fromJSON!(RecordType)(responseJSON);
recordOut = fromJSON(responseJSON);
return recordOut; return recordOut;
} }