diff --git a/include/trial/protocol/json/serialization/boost/hana.hpp b/include/trial/protocol/json/serialization/boost/hana.hpp new file mode 100644 index 0000000..1b0850e --- /dev/null +++ b/include/trial/protocol/json/serialization/boost/hana.hpp @@ -0,0 +1,90 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2021 Vinícius dos Santos Oliveira +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef TRIAL_PROTOCOL_JSON_SERIALIZATION_BOOST_HANA_HPP +#define TRIAL_PROTOCOL_JSON_SERIALIZATION_BOOST_HANA_HPP + +#include +#include +#include +#include + +namespace trial +{ +namespace protocol +{ +namespace serialization +{ + +template +struct save_overloader, + Value, + std::enable_if_t::value>> +{ + static void save(json::basic_oarchive& ar, + const Value& data, + const unsigned int /*protocol_version*/) + { + using string_view = core::detail::basic_string_view; + + ar.template save(); + boost::hana::for_each(data, [&ar](auto member) { + auto key = boost::hana::first(member); + ar.save(string_view(key.c_str(), boost::hana::size(key))); + // TODO: what if subvalue uses old reflection infra? then it + // requires us to write the necessary framing (begin_array and + // end_array) + ar << boost::hana::second(member); + }); + ar.template save(); + } +}; + +template +struct load_overloader, + Value, + std::enable_if_t::value>> +{ + static void load(json::basic_iarchive& ar, + Value& data, + const unsigned int /*protocol_version*/) + { + ar.template load(); + for (;;) { + if (ar.symbol() == json::token::symbol::end_object) { + ar.template load(); + break; + } + + // skip key + { + auto r = ar.reader(); + json::partial::skip(r); + ar.reader(std::move(r)); + } + // skip value + { + auto r = ar.reader(); + json::partial::skip(r); + ar.reader(std::move(r)); + } + + // TODO: actually decode stuff + //ar >> x; + } + ar.template load(); + } +}; + +} // namespace serialization +} // namespace protocol +} // namespace trial + +#endif // TRIAL_PROTOCOL_JSON_SERIALIZATION_BOOST_HANA_HPP diff --git a/test/json/CMakeLists.txt b/test/json/CMakeLists.txt index 875b4b2..3a8b37e 100644 --- a/test/json/CMakeLists.txt +++ b/test/json/CMakeLists.txt @@ -19,6 +19,7 @@ trial_add_test(json_writer_suite writer_suite.cpp) trial_add_test(json_iarchive_suite iarchive_suite.cpp) trial_add_test(json_oarchive_suite oarchive_suite.cpp) trial_add_test(json_partial_skip_suite skip_suite.cpp) +trial_add_test(hana_reflection_suite hana_reflection_suite.cpp) # Tree processing trial_add_test(json_parse_suite parse_suite.cpp) diff --git a/test/json/hana_reflection_suite.cpp b/test/json/hana_reflection_suite.cpp new file mode 100644 index 0000000..172a093 --- /dev/null +++ b/test/json/hana_reflection_suite.cpp @@ -0,0 +1,70 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2021 Vinícius dos Santos Oliveira +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +/////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include + +using namespace trial::protocol; + +//----------------------------------------------------------------------------- +// Basic types +//----------------------------------------------------------------------------- + +struct Foobar { + BOOST_HANA_DEFINE_STRUCT(Foobar, + (int, foo), + (int, bar), + (int, baz) + ); +}; + +namespace basic_suite +{ + +void test_oarchive() +{ + std::ostringstream result; + json::oarchive ar(result); + Foobar value{5, 10, 0}; + ar << value; + TRIAL_PROTOCOL_TEST_EQUAL(result.str(), "{\"foo\":5,\"bar\":10,\"baz\":0}"); +} + +void test_iarchive() +{ + const char input[] = "{\"foo\":5,\"bar\":10,\"baz\":0}"; + json::iarchive in(input); + Foobar value{1, 2, 3}; + TRIAL_PROTOCOL_TEST_NO_THROW(in >> value); + TRIAL_PROTOCOL_TEST_EQUAL(value.foo, 5); + TRIAL_PROTOCOL_TEST_EQUAL(value.bar, 10); + TRIAL_PROTOCOL_TEST_EQUAL(value.baz, 0); +} + +void run() +{ + test_oarchive(); + test_iarchive(); +} + +} // namespace basic_suite + +//----------------------------------------------------------------------------- +// main +//----------------------------------------------------------------------------- + +int main() +{ + basic_suite::run(); + + return boost::report_errors(); +}