Skip to content

Commit

Permalink
Merge pull request #1542 from rejectedsoftware/traits_based_serializers
Browse files Browse the repository at this point in the history
Let serializers get a type traits struct instead of the raw type.
  • Loading branch information
s-ludwig authored Aug 17, 2016
2 parents 907a826 + 23b072c commit 50cbbbb
Show file tree
Hide file tree
Showing 3 changed files with 264 additions and 144 deletions.
36 changes: 21 additions & 15 deletions source/vibe/data/bson.d
Original file line number Diff line number Diff line change
Expand Up @@ -1347,34 +1347,34 @@ struct BsonSerializer {
return ret;
}

void beginWriteDictionary(T)()
void beginWriteDictionary(Traits)()
{
writeCompositeEntryHeader(Bson.Type.object);
m_compositeStack ~= m_dst.data.length;
m_dst.put(toBsonData(cast(int)0));
}
void endWriteDictionary(T)()
void endWriteDictionary(Traits)()
{
m_dst.put(Bson.Type.end);
auto sh = m_compositeStack[$-1];
m_compositeStack.length--;
m_dst.data[sh .. sh + 4] = toBsonData(cast(uint)(m_dst.data.length - sh))[];
}
void beginWriteDictionaryEntry(T)(string name) { m_entryName = name; }
void endWriteDictionaryEntry(T)(string name) {}
void beginWriteDictionaryEntry(Traits)(string name) { m_entryName = name; }
void endWriteDictionaryEntry(Traits)(string name) {}

void beginWriteArray(T)(size_t)
void beginWriteArray(Traits)(size_t)
{
writeCompositeEntryHeader(Bson.Type.array);
m_compositeStack ~= m_dst.data.length;
m_dst.put(toBsonData(cast(int)0));
}
void endWriteArray(T)() { endWriteDictionary!T(); }
void beginWriteArrayEntry(T)(size_t idx) { m_entryIndex = idx; }
void endWriteArrayEntry(T)(size_t idx) {}
void endWriteArray(Traits)() { endWriteDictionary!Traits(); }
void beginWriteArrayEntry(Traits)(size_t idx) { m_entryIndex = idx; }
void endWriteArrayEntry(Traits)(size_t idx) {}

// auto ref does't work for DMD 2.064
void writeValue(T)(/*auto ref const*/ in T value) { writeValueH!(T, true)(value); }
void writeValue(Traits, T)(/*auto ref const*/ in T value) { writeValueH!(T, true)(value); }

private void writeValueH(T, bool write_header)(/*auto ref const*/ in T value)
{
Expand Down Expand Up @@ -1428,7 +1428,7 @@ struct BsonSerializer {
//
// deserialization
//
void readDictionary(T)(scope void delegate(string) entry_callback)
void readDictionary(Traits)(scope void delegate(string) entry_callback)
{
enforce(m_inputData.type == Bson.Type.object, "Expected object instead of "~m_inputData.type.to!string());
auto old = m_inputData;
Expand All @@ -1439,7 +1439,10 @@ struct BsonSerializer {
m_inputData = old;
}

void readArray(T)(scope void delegate(size_t) size_callback, scope void delegate() entry_callback)
void beginReadDictionaryEntry(Traits)(string name) {}
void endReadDictionaryEntry(Traits)(string name) {}

void readArray(Traits)(scope void delegate(size_t) size_callback, scope void delegate() entry_callback)
{
enforce(m_inputData.type == Bson.Type.array, "Expected array instead of "~m_inputData.type.to!string());
auto old = m_inputData;
Expand All @@ -1450,7 +1453,10 @@ struct BsonSerializer {
m_inputData = old;
}

T readValue(T)()
void beginReadArrayEntry(Traits)(size_t index) {}
void endReadArrayEntry(Traits)(size_t index) {}

T readValue(Traits, T)()
{
static if (is(T == Bson)) return m_inputData;
else static if (is(T == Json)) return m_inputData.toJson();
Expand All @@ -1473,8 +1479,8 @@ struct BsonSerializer {
if (m_inputData.type == Bson.Type.string) return SysTime.fromISOExtString(m_inputData.get!string);
else return m_inputData.get!BsonDate().toSysTime();
}
else static if (isBsonSerializable!T) return T.fromBson(readValue!Bson);
else static if (isJsonSerializable!T) return T.fromJson(readValue!Bson.toJson());
else static if (isBsonSerializable!T) return T.fromBson(readValue!(Traits, Bson));
else static if (isJsonSerializable!T) return T.fromJson(readValue!(Traits, Bson).toJson());
else static if (is(T : const(ubyte)[])) {
auto ret = m_inputData.get!BsonBinData.rawData;
static if (isStaticArray!T) return cast(T)ret[0 .. T.length];
Expand All @@ -1483,7 +1489,7 @@ struct BsonSerializer {
} else return m_inputData.get!T();
}

bool tryReadNull()
bool tryReadNull(Traits)()
{
if (m_inputData.type == Bson.Type.null_) return true;
return false;
Expand Down
68 changes: 40 additions & 28 deletions source/vibe/data/json.d
Original file line number Diff line number Diff line change
Expand Up @@ -1575,30 +1575,30 @@ struct JsonSerializer {
// serialization
//
Json getSerializedResult() { return m_current; }
void beginWriteDictionary(T)() { m_compositeStack ~= Json.emptyObject; }
void endWriteDictionary(T)() { m_current = m_compositeStack[$-1]; m_compositeStack.length--; }
void beginWriteDictionaryEntry(T)(string name) {}
void endWriteDictionaryEntry(T)(string name) { m_compositeStack[$-1][name] = m_current; }
void beginWriteDictionary(Traits)() { m_compositeStack ~= Json.emptyObject; }
void endWriteDictionary(Traits)() { m_current = m_compositeStack[$-1]; m_compositeStack.length--; }
void beginWriteDictionaryEntry(Traits)(string name) {}
void endWriteDictionaryEntry(Traits)(string name) { m_compositeStack[$-1][name] = m_current; }

void beginWriteArray(T)(size_t) { m_compositeStack ~= Json.emptyArray; }
void endWriteArray(T)() { m_current = m_compositeStack[$-1]; m_compositeStack.length--; }
void beginWriteArrayEntry(T)(size_t) {}
void endWriteArrayEntry(T)(size_t) { m_compositeStack[$-1].appendArrayElement(m_current); }
void beginWriteArray(Traits)(size_t) { m_compositeStack ~= Json.emptyArray; }
void endWriteArray(Traits)() { m_current = m_compositeStack[$-1]; m_compositeStack.length--; }
void beginWriteArrayEntry(Traits)(size_t) {}
void endWriteArrayEntry(Traits)(size_t) { m_compositeStack[$-1].appendArrayElement(m_current); }

void writeValue(T)(in T value)
void writeValue(Traits, T)(in T value)
if (!is(T == Json))
{
static if (isJsonSerializable!T) m_current = value.toJson();
else m_current = Json(value);
}

void writeValue(T)(Json value) if (is(T == Json)) { m_current = value; }
void writeValue(T)(in Json value) if (is(T == Json)) { m_current = value.clone; }
void writeValue(Traits, T)(Json value) if (is(T == Json)) { m_current = value; }
void writeValue(Traits, T)(in Json value) if (is(T == Json)) { m_current = value.clone; }

//
// deserialization
//
void readDictionary(T)(scope void delegate(string) field_handler)
void readDictionary(Traits)(scope void delegate(string) field_handler)
{
enforceJson(m_current.type == Json.Type.object, "Expected JSON object, got "~m_current.type.to!string);
auto old = m_current;
Expand All @@ -1609,7 +1609,10 @@ struct JsonSerializer {
m_current = old;
}

void readArray(T)(scope void delegate(size_t) size_callback, scope void delegate() entry_callback)
void beginReadDictionaryEntry(Traits)(string name) {}
void endReadDictionaryEntry(Traits)(string name) {}

void readArray(Traits)(scope void delegate(size_t) size_callback, scope void delegate() entry_callback)
{
enforceJson(m_current.type == Json.Type.array, "Expected JSON array, got "~m_current.type.to!string);
auto old = m_current;
Expand All @@ -1621,7 +1624,10 @@ struct JsonSerializer {
m_current = old;
}

T readValue(T)()
void beginReadArrayEntry(Traits)(size_t index) {}
void endReadArrayEntry(Traits)(size_t index) {}

T readValue(Traits, T)()
{
static if (is(T == Json)) return m_current;
else static if (isJsonSerializable!T) return T.fromJson(m_current);
Expand All @@ -1638,7 +1644,7 @@ struct JsonSerializer {
}
}

bool tryReadNull() { return m_current.type == Json.Type.null_; }
bool tryReadNull(Traits)() { return m_current.type == Json.Type.null_; }
}


Expand Down Expand Up @@ -1676,24 +1682,24 @@ struct JsonStringSerializer(R, bool pretty = false)

void getSerializedResult() {}

void beginWriteDictionary(T)() { startComposite(); m_range.put('{'); }
void endWriteDictionary(T)() { endComposite(); m_range.put("}"); }
void beginWriteDictionaryEntry(T)(string name)
void beginWriteDictionary(Traits)() { startComposite(); m_range.put('{'); }
void endWriteDictionary(Traits)() { endComposite(); m_range.put("}"); }
void beginWriteDictionaryEntry(Traits)(string name)
{
startCompositeEntry();
m_range.put('"');
m_range.jsonEscape(name);
static if (pretty) m_range.put(`": `);
else m_range.put(`":`);
}
void endWriteDictionaryEntry(T)(string name) {}
void endWriteDictionaryEntry(Traits)(string name) {}

void beginWriteArray(T)(size_t) { startComposite(); m_range.put('['); }
void endWriteArray(T)() { endComposite(); m_range.put(']'); }
void beginWriteArrayEntry(T)(size_t) { startCompositeEntry(); }
void endWriteArrayEntry(T)(size_t) {}
void beginWriteArray(Traits)(size_t) { startComposite(); m_range.put('['); }
void endWriteArray(Traits)() { endComposite(); m_range.put(']'); }
void beginWriteArrayEntry(Traits)(size_t) { startCompositeEntry(); }
void endWriteArrayEntry(Traits)(size_t) {}

void writeValue(T)(in T value)
void writeValue(Traits, T)(in T value)
{
static if (is(T == typeof(null))) m_range.put("null");
else static if (is(T == bool)) m_range.put(value ? "true" : "false");
Expand Down Expand Up @@ -1750,7 +1756,7 @@ struct JsonStringSerializer(R, bool pretty = false)
int m_line = 0;
}

void readDictionary(T)(scope void delegate(string) entry_callback)
void readDictionary(Traits)(scope void delegate(string) entry_callback)
{
m_range.skipWhitespace(&m_line);
enforceJson(!m_range.empty && m_range.front == '{', "Expecting object.");
Expand Down Expand Up @@ -1778,7 +1784,10 @@ struct JsonStringSerializer(R, bool pretty = false)
}
}

void readArray(T)(scope void delegate(size_t) size_callback, scope void delegate() entry_callback)
void beginReadDictionaryEntry(Traits)(string name) {}
void endReadDictionaryEntry(Traits)(string name) {}

void readArray(Traits)(scope void delegate(size_t) size_callback, scope void delegate() entry_callback)
{
m_range.skipWhitespace(&m_line);
enforceJson(!m_range.empty && m_range.front == '[', "Expecting array.");
Expand All @@ -1799,7 +1808,10 @@ struct JsonStringSerializer(R, bool pretty = false)
}
}

T readValue(T)()
void beginReadArrayEntry(Traits)(size_t index) {}
void endReadArrayEntry(Traits)(size_t index) {}

T readValue(Traits, T)()
{
m_range.skipWhitespace(&m_line);
static if (is(T == typeof(null))) { enforceJson(m_range.take(4).equal("null"), "Expecting 'null'."); return null; }
Expand Down Expand Up @@ -1836,7 +1848,7 @@ struct JsonStringSerializer(R, bool pretty = false)
else static assert(false, "Unsupported type: " ~ T.stringof);
}

bool tryReadNull()
bool tryReadNull(Traits)()
{
m_range.skipWhitespace(&m_line);
if (m_range.front != 'n') return false;
Expand Down
Loading

0 comments on commit 50cbbbb

Please sign in to comment.