Skip to content

Commit

Permalink
leaner number (de)serialization & static arrays
Browse files Browse the repository at this point in the history
  • Loading branch information
WebFreak001 committed Jan 23, 2019
1 parent fd6f6eb commit d6a655e
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 13 deletions.
45 changes: 45 additions & 0 deletions source/mongoschema/db.d
Original file line number Diff line number Diff line change
Expand Up @@ -832,6 +832,17 @@ unittest
Activity activity = Activity.Medium;
BitFlags!Permission permissions;
Tuple!(string, string) name;
ubyte x0;
byte x1;
ushort x2;
short x3;
uint x4;
int x5;
ulong x6;
long x7;
float x8;
double x9;
int[10] token;

Bson encodePassword(UserSchema user)
{
Expand All @@ -845,6 +856,17 @@ unittest
user.username = "Bob";
user.permissions = Permission.A | Permission.C;
user.name = tuple("Bob", "Bobby");
user.x0 = 7;
user.x1 = 7;
user.x2 = 7;
user.x3 = 7;
user.x4 = 7;
user.x5 = 7;
user.x6 = 7;
user.x7 = 7;
user.x8 = 7;
user.x9 = 7;
user.token[3] = 8;
auto bson = user.toSchemaBson();
assert(bson["username"].get!string == "Bob");
assert(bson["date-created"].get!(BsonDate).value > 0);
Expand All @@ -853,6 +875,18 @@ unittest
assert(bson["password"].get!(BsonBinData).rawData == sha1Of(user.password ~ user.salt));
assert(bson["permissions"].get!(int) == 5);
assert(bson["name"].get!(Bson[]).length == 2);
assert(bson["x0"].get!int == 7);
assert(bson["x1"].get!int == 7);
assert(bson["x2"].get!int == 7);
assert(bson["x3"].get!int == 7);
assert(bson["x4"].get!int == 7);
assert(bson["x5"].get!int == 7);
assert(bson["x6"].get!long == 7);
assert(bson["x7"].get!long == 7);
assert(bson["x8"].get!double == 7);
assert(bson["x9"].get!double == 7);
assert(bson["token"].get!(Bson[]).length == 10);
assert(bson["token"].get!(Bson[])[3].get!int == 8);

auto user2 = bson.fromSchemaBson!UserSchema();
assert(user2.username == user.username);
Expand All @@ -863,6 +897,17 @@ unittest
assert(user2.activity == user.activity);
assert(user2.permissions == user.permissions);
assert(user2.name == user.name);
assert(user2.x0 == user.x0);
assert(user2.x1 == user.x1);
assert(user2.x2 == user.x2);
assert(user2.x3 == user.x3);
assert(user2.x4 == user.x4);
assert(user2.x5 == user.x5);
assert(user2.x6 == user.x6);
assert(user2.x7 == user.x7);
assert(user2.x8 == user.x8);
assert(user2.x9 == user.x9);
assert(user2.token == user.token);
}

// version(TestDB):
Expand Down
49 changes: 36 additions & 13 deletions source/mongoschema/package.d
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
module mongoschema;

import core.time;
import std.array : appender;
import std.conv;
import std.traits;
import std.typecons : BitFlags, isTuple;
public import vibe.data.bson;
Expand Down Expand Up @@ -172,19 +174,33 @@ T bsonToMember(T)(auto ref T member, Bson value)
auto bsons = value.get!(Bson[]);
T values;
foreach (i, val; values)
{
values[i] = bsonToMember!(typeof(val))(values[i], bsons[i]);
}
return values;
}
else static if (isArray!T && !isSomeString!T)
else static if (isDynamicArray!T && !isSomeString!T)
{ // Arrays of anything except strings
alias Type = typeof(member[0]);
if (value.type != Bson.Type.array)
throw new Exception("Cannot convert from BSON type " ~ value.type.to!string ~ " to array");
auto arr = value.get!(Bson[]);
auto ret = appender!T();
ret.reserve(arr.length);
foreach (val; arr)
ret.put(bsonToMember!Type(Type.init, val));
return ret.data;
}
else static if (isStaticArray!T)
{ // Arrays of anything except strings
alias Type = typeof(member[0]);
T values;
foreach (val; value)
{
values ~= bsonToMember!Type(Type.init, val);
}
if (value.type != Bson.Type.array)
throw new Exception("Cannot convert from BSON type " ~ value.type.to!string ~ " to array");
auto arr = value.get!(Bson[]);
if (arr.length != values.length)
throw new Exception("Cannot convert from BSON array of length "
~ arr.length.to!string ~ " to array of length " ~ arr.length.to!string);
foreach (i, val; arr)
values[i] = bsonToMember!Type(Type.init, val);
return values;
}
else static if (isAssociativeArray!T)
Expand All @@ -200,13 +216,20 @@ T bsonToMember(T)(auto ref T member, Bson value)
{ // Already a Bson object
return value;
}
else static if (isNumeric!T)
{
if (value.type == Bson.Type.int_)
return cast(T) value.get!int;
else if (value.type == Bson.Type.long_)
return cast(T) value.get!long;
else if (value.type == Bson.Type.double_)
return cast(T) value.get!double;
else
throw new Exception(
"Cannot convert BSON from type " ~ value.type.to!string ~ " to " ~ T.stringof);
}
else static if (__traits(compiles, { value.get!T(); }))
{ // Check if this can be passed
static if (is(T == long))
{ // If the output expects a long, but the data is a int, do .get!int
if (value.type == Bson.Type.int_)
return value.get!int();
}
{
return value.get!T();
}
else static if (!isBasicType!T)
Expand Down

0 comments on commit d6a655e

Please sign in to comment.