getml / reflect-cpp

A C++20 library for fast serialization, deserialization and validation using reflection. Supports JSON, BSON, CBOR, flexbuffers, msgpack, TOML, XML, YAML / msgpack.org[C++20]
https://getml.github.io/reflect-cpp/
MIT License
901 stars 76 forks source link

Redesign the Writer #36

Closed liuzicheng1987 closed 6 months ago

liuzicheng1987 commented 8 months ago

The Reader and Writer have been designed with various JSON libraries in mind. Whereas the design for Reader seems fine, the Writer needs an update.

The problem is that many libraries for binary formats require you to directly assign children to their parents as opposed to first creating the children and then assigning them to their parents.

For instance, pugixml requires you to do this:

auto node_child = node_parent.append_child(_key.c_str());

Likewise, libbson (https://mongoc.org/libbson/current/creating.html):

bson_append_array_builder_begin (&parent, "foo", 3, &bab);
bson_array_builder_append_int32 (bab, 9);
bson_array_builder_append_int32 (bab, 8);
bson_array_builder_append_int32 (bab, 7);
bson_append_array_builder_end (&parent, bab);

The current workaround it to have structures like OutputArray and OutputObject (https://github.com/getml/reflect-cpp/blob/f/xml/include/rfl/flexbuf/OutputArray.hpp). This works well, but it adds an unnecessary extra layer and runtime overhead.

This could be avoided by a redesign of the writer that takes these limitations into account.

jimixxperez commented 8 months ago

I personally don't think the Writer and Reader interfaces (with associated Parser) don't provide the clearest and flexible approach - especially in comparison to Rust Serdes design. Even though Rust native traits don't have a natural match in cpp we could strive a similar approach.

liuzicheng1987 commented 7 months ago

@jimixxperez, would that mean that the users of our library would have to inherit some base class from our library? Or how would users then implement the "traits" on their structs?