Skip to content

Instantly share code, notes, and snippets.

@vinipsmaker
Created July 20, 2021 00:47
Show Gist options
  • Save vinipsmaker/c740d6386308cb685c95ef4b4851d0db to your computer and use it in GitHub Desktop.
Save vinipsmaker/c740d6386308cb685c95ef4b4851d0db to your computer and use it in GitHub Desktop.

Trial.Protocol: Serialization docs

Boost.Serialization exposes an interface to read and write S-exprs. When you define codecs to your data structures in this manner, you’re only defining the mapping between your data structures and S-exprs. The JSON format can represent S-exprs easily through arrays.

struct Foobar {
    int foo;
    int bar;
    int baz;
};

json::oarchive ar;
Foobar value{5, 10, 0};
ar << value;

Given the proper codecs are available, code such as the above would generate a JSON document such as:

[5, 10, 0]

However JSON users expect a different kind of serialization for their types. A common expectation would be:

{
    "foo": 5,
    "bar": 10,
    "baz": 0
}

Nonetheless it’s still doable to use Boost.Serialization machinery and Trial.Protocol to generate this type of result. Boost.Serialization’s contract to define the S-expr mapping is an user-written function in the likes of:

template<class Archive>
void save(Archive& ar, const Foobar& value,
          const unsigned int version)
{
    ar << value.foo;
    ar << value.bar;
    ar << value.baz;
}

So we can simply add a new overload that works on JSON archives directly to define the JSON mapping:

template<class CharT>
void save(json::basic_oarchive<CharT>& ar,
          const Foobar& value,
          const unsigned int version)
{
    ar.template save<json::token::begin_object>();
    ar.save("foo");
    ar.save(value.foo);
    ar.save("bar");
    ar.save(value.bar);
    ar.save("baz");
    ar.save(value.baz);
    ar.template save<json::token::end_object>();
}

Internally Trial.Protocol does more stuff to reuse S-exprs mappings mixed with JSON mappings, but that’s basically what you need to understand. If you use boost::hana::Struct to describe your types then Trial.Protocol already offers the JSON mapping for free:

struct Foobar {
    BOOST_HANA_DEFINE_STRUCT(Foobar,
        (int, foo),
        (int, bar),
        (int, baz)
    );
};

json::oarchive ar;
Foobar value{5, 10, 0};
ar << value;

And this code will generate the expected JSON:

{
    "foo": 5,
    "bar": 10,
    "baz": 0
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment