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
Serialization rework #2503
Serialization rework #2503
Conversation
49a640a
to
81a348a
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.
Nice! A couple comments. Would this also allow one to use std_data_json
instead of vibe.data.json
? Maybe an example of this could be useful for user code.
web/vibe/web/common.d
Outdated
static void serialize(R)(ref R output_range, ref Point value) | ||
{ | ||
output_range.put(nativeToBigEndian(value.x)); | ||
output_range.put(nativeToBigEndian(value.y)); | ||
} |
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.
Can you extend the example to use an overload set (on value
) ?
Also, maybe make value
be const
?
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.
Made it const and turned it into a template parameter. Overload set would also be possible with the latest changes, that could maybe be added as a second example? But it does get quite lengthy then.
Hm, while writing the parameter documentation for |
1e745f1
to
145944d
Compare
In theory yes, but is there a serializer implementation for it? |
thanks for cleaning up my PR @s-ludwig |
Now follows the same structure as the other new stream APIs.
Previously required a random access range.
- Adds a documentation comment and an example to resultSerializer - Both, serialize() and deserialize(), work on ranges of ubyte now Note that this might later be extended to allow ranges of char, but for now this is the more generic baseline implementation.
- Renamed isSerializerSupportSinkType to doesSerializerSupportStringSink and made it independent of the serialized type - Adds support for output range based string sink serialization in addition to delegate based - Sink serialization takes precedence independently of the used serializer to enforce consistent semantics - Fixes JsonStringSerializer to escape strings written with the sink approach - Fixes the documentation order of string serialization vs. sink serialization
version(unittest) caused some nasty linker issues in the past.
User code might want to ensure that custom types match this trait.
Allows to use overload sets and template functions for generic deserialization.
5e2d5f0
to
d46728a
Compare
I don't think the
|
All of these would only work under the assumption that the serializer performs a recursive construction of the result value using constructor calls. I don't think that this is realistic for a generic serializer for multiple reasons. Also, the init state is practically mandated by the language to be valid anyway. Returning large structs by value, where performing an extra copy is a performance issue (in the same order of magnitude as the serialization and the network transfer), doesn't sound like a good idea, too, at least I wouldn't count on the library handling it with NRVO throughout if I were a user. So while I do understand that these are issues in theory, I'm not really convinced that they are in practice. The counter argument is pretty simple, but maybe you have a better idea how to solve it: Having it as a return value means that |
Well, constructor is one thing, but the serializer an also define a hook (a la
It's mandated to exist. But some types need to be constructed to be valid, which is a common complain in D.
Well, those are drawn from experience writing a deserializer. Namely, this. The reason for doing so was that we needed to have, in our REST API, types that are not under our control. Those types are The TL;DR from my experience was: If you want a generic serializer, it needs to handle const/immutable/shared.
I'm not sure I follow. If you can provide an instance of the type to be filled, you can provide the |
If the copy constructor is the issue, then why not just move the value instead of copying? In your Example:
How to invoke |
It breaks internal pointers. Which are invalid in D, but not in C++. And even in D, I know Weka is using them for example.
Not only. Any type is able to explicitly support the serialization by specifying the static I would really have to have a way to provide a pattern matcher to the function, but I haven't found quite the right approach yet.
The API I went with requires you to provide the type you want as template parameter. E.g. |
Serialization of possibly immutable C++ structs with internal pointers, set up in D, which may choose to move the struct implicitly, still sounds like a rather esoteric and dangerous combination to me (although I see how this could come up in custom IPC scenarios), and nothing to endorse. But since you have practical evidence I obviously can't really dismiss it. So then that means it's template-only serialization, which, since it matches the general serialization API, is really not a big deal. Being able to work with concrete types and overload sets would have been nice, though. |
Allows to construct types with assignment restrictions with the trade-off of requiring generic serializer definitions instead of overload sets.
4e61a3f
to
e359cfb
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.
LGTM. What's your timeline for a release ? We're going to try it out in our app very soon.
We can do a beta release immediately and I'll update the change log ASAP. |
This follows up on #2492 and #2493 and addresses the remaining issues. @ferencdg, please comment on any issues you might see, I could have broken a use case that I didn't see here.