Skip to content

Commit d6a655e

Browse files
committed
leaner number (de)serialization & static arrays
1 parent fd6f6eb commit d6a655e

File tree

2 files changed

+81
-13
lines changed

2 files changed

+81
-13
lines changed

source/mongoschema/db.d

+45
Original file line numberDiff line numberDiff line change
@@ -832,6 +832,17 @@ unittest
832832
Activity activity = Activity.Medium;
833833
BitFlags!Permission permissions;
834834
Tuple!(string, string) name;
835+
ubyte x0;
836+
byte x1;
837+
ushort x2;
838+
short x3;
839+
uint x4;
840+
int x5;
841+
ulong x6;
842+
long x7;
843+
float x8;
844+
double x9;
845+
int[10] token;
835846

836847
Bson encodePassword(UserSchema user)
837848
{
@@ -845,6 +856,17 @@ unittest
845856
user.username = "Bob";
846857
user.permissions = Permission.A | Permission.C;
847858
user.name = tuple("Bob", "Bobby");
859+
user.x0 = 7;
860+
user.x1 = 7;
861+
user.x2 = 7;
862+
user.x3 = 7;
863+
user.x4 = 7;
864+
user.x5 = 7;
865+
user.x6 = 7;
866+
user.x7 = 7;
867+
user.x8 = 7;
868+
user.x9 = 7;
869+
user.token[3] = 8;
848870
auto bson = user.toSchemaBson();
849871
assert(bson["username"].get!string == "Bob");
850872
assert(bson["date-created"].get!(BsonDate).value > 0);
@@ -853,6 +875,18 @@ unittest
853875
assert(bson["password"].get!(BsonBinData).rawData == sha1Of(user.password ~ user.salt));
854876
assert(bson["permissions"].get!(int) == 5);
855877
assert(bson["name"].get!(Bson[]).length == 2);
878+
assert(bson["x0"].get!int == 7);
879+
assert(bson["x1"].get!int == 7);
880+
assert(bson["x2"].get!int == 7);
881+
assert(bson["x3"].get!int == 7);
882+
assert(bson["x4"].get!int == 7);
883+
assert(bson["x5"].get!int == 7);
884+
assert(bson["x6"].get!long == 7);
885+
assert(bson["x7"].get!long == 7);
886+
assert(bson["x8"].get!double == 7);
887+
assert(bson["x9"].get!double == 7);
888+
assert(bson["token"].get!(Bson[]).length == 10);
889+
assert(bson["token"].get!(Bson[])[3].get!int == 8);
856890

857891
auto user2 = bson.fromSchemaBson!UserSchema();
858892
assert(user2.username == user.username);
@@ -863,6 +897,17 @@ unittest
863897
assert(user2.activity == user.activity);
864898
assert(user2.permissions == user.permissions);
865899
assert(user2.name == user.name);
900+
assert(user2.x0 == user.x0);
901+
assert(user2.x1 == user.x1);
902+
assert(user2.x2 == user.x2);
903+
assert(user2.x3 == user.x3);
904+
assert(user2.x4 == user.x4);
905+
assert(user2.x5 == user.x5);
906+
assert(user2.x6 == user.x6);
907+
assert(user2.x7 == user.x7);
908+
assert(user2.x8 == user.x8);
909+
assert(user2.x9 == user.x9);
910+
assert(user2.token == user.token);
866911
}
867912

868913
// version(TestDB):

source/mongoschema/package.d

+36-13
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
module mongoschema;
22

33
import core.time;
4+
import std.array : appender;
5+
import std.conv;
46
import std.traits;
57
import std.typecons : BitFlags, isTuple;
68
public import vibe.data.bson;
@@ -172,19 +174,33 @@ T bsonToMember(T)(auto ref T member, Bson value)
172174
auto bsons = value.get!(Bson[]);
173175
T values;
174176
foreach (i, val; values)
175-
{
176177
values[i] = bsonToMember!(typeof(val))(values[i], bsons[i]);
177-
}
178178
return values;
179179
}
180-
else static if (isArray!T && !isSomeString!T)
180+
else static if (isDynamicArray!T && !isSomeString!T)
181+
{ // Arrays of anything except strings
182+
alias Type = typeof(member[0]);
183+
if (value.type != Bson.Type.array)
184+
throw new Exception("Cannot convert from BSON type " ~ value.type.to!string ~ " to array");
185+
auto arr = value.get!(Bson[]);
186+
auto ret = appender!T();
187+
ret.reserve(arr.length);
188+
foreach (val; arr)
189+
ret.put(bsonToMember!Type(Type.init, val));
190+
return ret.data;
191+
}
192+
else static if (isStaticArray!T)
181193
{ // Arrays of anything except strings
182194
alias Type = typeof(member[0]);
183195
T values;
184-
foreach (val; value)
185-
{
186-
values ~= bsonToMember!Type(Type.init, val);
187-
}
196+
if (value.type != Bson.Type.array)
197+
throw new Exception("Cannot convert from BSON type " ~ value.type.to!string ~ " to array");
198+
auto arr = value.get!(Bson[]);
199+
if (arr.length != values.length)
200+
throw new Exception("Cannot convert from BSON array of length "
201+
~ arr.length.to!string ~ " to array of length " ~ arr.length.to!string);
202+
foreach (i, val; arr)
203+
values[i] = bsonToMember!Type(Type.init, val);
188204
return values;
189205
}
190206
else static if (isAssociativeArray!T)
@@ -200,13 +216,20 @@ T bsonToMember(T)(auto ref T member, Bson value)
200216
{ // Already a Bson object
201217
return value;
202218
}
219+
else static if (isNumeric!T)
220+
{
221+
if (value.type == Bson.Type.int_)
222+
return cast(T) value.get!int;
223+
else if (value.type == Bson.Type.long_)
224+
return cast(T) value.get!long;
225+
else if (value.type == Bson.Type.double_)
226+
return cast(T) value.get!double;
227+
else
228+
throw new Exception(
229+
"Cannot convert BSON from type " ~ value.type.to!string ~ " to " ~ T.stringof);
230+
}
203231
else static if (__traits(compiles, { value.get!T(); }))
204-
{ // Check if this can be passed
205-
static if (is(T == long))
206-
{ // If the output expects a long, but the data is a int, do .get!int
207-
if (value.type == Bson.Type.int_)
208-
return value.get!int();
209-
}
232+
{
210233
return value.get!T();
211234
}
212235
else static if (!isBasicType!T)

0 commit comments

Comments
 (0)