New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added sink type toString to the serialization #2493
Conversation
data/vibe/data/serialization.d
Outdated
@@ -475,7 +475,10 @@ private template serializeValueImpl(Serializer, alias Policy) { | |||
ser.serializeValue!(CustomType, ATTRIBUTES)(value.toRepresentation()); | |||
} else static if (isISOExtStringSerializable!TU) { | |||
ser.serializeValue!(string, ATTRIBUTES)(value.toISOExtString()); | |||
} else static if (isStringSerializable!TU) { | |||
} else static if (ObjectSupportSinkType!TU && SerializerSupportSinkType!(Serializer, TU)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ObjectSupportSinkType is not technically needed as SerializerSupportSinkType implicitly checks for the same
data/vibe/data/json.d
Outdated
dg = (scope const(char)[] data) | ||
{ | ||
static if (__traits(compiles, m_range ~= data)) | ||
m_range ~= data; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in case the OutputRange supports more than just the put method(like with Appender) and operator~ is more optimized
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be better to have this as a comment in the code ;)
549f6a0
to
acff461
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The duplication between serializer and object handling looks a bit odd to me, but I'm not familiar enough with the code to suggest an alternative (or be 100% sure there's a better way either). So LGTM, minus a few comments. @s-ludwig ?
data/vibe/data/json.d
Outdated
dg = (scope const(char)[] data) | ||
{ | ||
static if (__traits(compiles, m_range ~= data)) | ||
m_range ~= data; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be better to have this as a comment in the code ;)
data/vibe/data/serialization.d
Outdated
import std.format : formattedWrite; | ||
import vibe.data.json; | ||
|
||
struct X (alias T) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
struct X (alias T) | |
struct X (bool hasSink) |
Would be more descriptive, wouldn't it ?
data/vibe/data/json.d
Outdated
static if (isOutputRange!(R, char)) | ||
{ | ||
dg = (scope const(char)[] data) | ||
{ | ||
static if (__traits(compiles, m_range ~= data)) | ||
m_range ~= data; | ||
else | ||
foreach (const c; data) | ||
m_range.put(c); | ||
}; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having this delegate in the ctor has the downside of creating an extra GC allocation and an extra reference to m_range
through the context.
It would be much better to move this delegate to the function that pass it (serializeSinkType
) and use scope
.
But even better, you could just make it a private method and pass &this.sink
at L2028 instead of dg
.
data/vibe/data/serialization.d
Outdated
} | ||
|
||
/// | ||
package template isObjectSupportSinkType (ObjectT) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
package template isObjectSupportSinkType (ObjectT) | |
package template isSinkSerializable (ObjectT) |
I think the name is shorter and still fits with the existing style, what do you think ?
data/vibe/data/serialization.d
Outdated
/// | ||
package template isObjectSupportSinkType (ObjectT) | ||
{ | ||
enum isObjectSupportSinkType = is(typeof(ObjectT.toString(cast(SerializeSinkDg) null)) == void) && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
enum isObjectSupportSinkType = is(typeof(ObjectT.toString(cast(SerializeSinkDg) null)) == void) && | |
enum isObjectSupportSinkType = is(typeof(ObjectT.toString(SerializeSinkDg.init))) && |
X.init
is a neat way to get a default value typed as X
. Remember, every cast is an aberration ;)
And I don't think we need to force the return type to be void
. Why would we ?
data/vibe/data/serialization.d
Outdated
private string s; | ||
this (int i, string s) @safe {this.i = i; this.s = s;} | ||
|
||
static if(T) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Space
data/vibe/data/serialization.d
Outdated
{ | ||
private int i; | ||
private string s; | ||
this (int i, string s) @safe {this.i = i; this.s = s;} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it's a struct, you don't need the ctor, do you ?
If you do, missing attributes.
data/vibe/data/serialization.d
Outdated
} | ||
} | ||
|
||
public string toString () @safe |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
public string toString () @safe | |
public string toString () const @safe |
data/vibe/data/serialization.d
Outdated
/// | ||
package template isSerializerSupportSinkType (SerT, ObjT) | ||
{ | ||
enum isSerializerSupportSinkType = is(typeof(SerT.serializeSinkType!(ObjT)(ObjT.init)) == void); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment about void
return as below
7adf705
to
80f1bb9
Compare
we have serializers like JsonSerializer(differenet from JsonStringSerializer) and JsonSerializer writes into a Json temporary object instead of an OutputRange. Because of this my thinking was that this sink serialization has to be supported by both the object and the serializer |
This change should reduce the number of memory allocations when using toString custom serialization
69fff52
to
39a280f
Compare
{ | ||
static if (isOutputRange!(R, char)) | ||
{ | ||
static if (__traits(compiles, m_range ~= data)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs to perform jsonEscape
, or is the idea is that the object is coupled with the output serialization format and can write arbitrary data?
This change should reduce the number of memory allocations when using toString custom serialization