diff options
| -rw-r--r-- | libnvxx/nvxx_serialize.h | 71 | ||||
| -rw-r--r-- | libnvxx/tests/nvxx_serialize.cc | 34 |
2 files changed, 101 insertions, 4 deletions
diff --git a/libnvxx/nvxx_serialize.h b/libnvxx/nvxx_serialize.h index 39a09fd..90918a7 100644 --- a/libnvxx/nvxx_serialize.h +++ b/libnvxx/nvxx_serialize.h @@ -261,8 +261,33 @@ struct nv_decoder<std::optional<_T>> { * object (de)serialization */ +namespace __detail { + +struct __serializer_tag { + using __serializer_tag_t = int; +}; + +template<typename _T> +concept __serializer = + requires(_T __t) { + typename _T::__serializer_tag_t; + }; +#if 0 + requires(_T __t) { + typename _T::__object_type_t; + } + && requires(_T &__t, nv_list &__nvl, + const_nv_list &__cnvl, + typename _T::__object_type_t &__e) { + __t.serialize(__nvl, __e); + __t.deserialize(__cnvl, __e); +}; +#endif + +} // namespace detail + template<typename _Object, typename _Member> -struct nv_field { +struct nv_field : __detail::__serializer_tag { nv_field(std::string __name, _Member _Object::* __ptr) : __field_name(__name) , __field_ptr(__ptr) @@ -285,10 +310,43 @@ private: _Member _Object::* __field_ptr; }; +template<typename _Member> +struct nv_literal; + +template<> +struct nv_literal<std::string_view> : __detail::__serializer_tag { + nv_literal(std::string __name, std::string __value) + : __field_name(__name) + , __field_value(__value) + { + } + + template<typename _Object> + auto serialize(nv_list &__nvl, _Object const &) { + __nvl.add_string(__field_name, __field_value); + } + + template<typename _Object> + auto deserialize(const_nv_list const &__nvl, _Object &) { + auto __value = __nvl.get_string(__field_name); + // TODO: possibly we could have a specific exception for this + if (__value != __field_value) + throw nv_key_not_found(__field_name); + } + +private: + std::string __field_name; + std::string __field_value; +}; + +nv_literal(std::string, char const *) -> nv_literal<std::string_view>; +nv_literal(std::string, std::string) -> nv_literal<std::string_view>; +nv_literal(std::string, std::string_view) -> nv_literal<std::string_view>; + namespace __detail { -template<typename _First, typename _Second> -struct __field_sequence { +template<__serializer _First, __serializer _Second> +struct __field_sequence : __detail::__serializer_tag { __field_sequence(_First __first_, _Second __second_) : __first(__first_) , __second(__second_) @@ -314,6 +372,7 @@ private: } // namespace __detail +#if 0 template<typename _Object, typename _M1, typename _M2> auto operator>> (nv_field<_Object, _M1> const &__f1, nv_field<_Object, _M2> const &__f2) @@ -327,6 +386,12 @@ auto operator>> (__detail::__field_sequence<__first, __second> const &__f1, { return (__detail::__field_sequence(__f1, __f2)); } +#endif +auto operator>> (__detail::__serializer auto const &__f1, + __detail::__serializer auto const &__f2) +{ + return (__detail::__field_sequence(__f1, __f2)); +} template<typename _Object, typename _Member> nv_field(std::string_view, _Member _Object::*) diff --git a/libnvxx/tests/nvxx_serialize.cc b/libnvxx/tests/nvxx_serialize.cc index 9d1f219..c3db5e2 100644 --- a/libnvxx/tests/nvxx_serialize.cc +++ b/libnvxx/tests/nvxx_serialize.cc @@ -188,7 +188,8 @@ struct object { template<> struct bsd::nv_schema<::object> { auto get() { - return (bsd::nv_field("int value", &object::int_value) + return (bsd::nv_literal("object type", "object") + >> bsd::nv_field("int value", &object::int_value) >> bsd::nv_field("string value", &object::string_value) >> bsd::nv_field("array value", &object::array_value)); } @@ -207,6 +208,35 @@ TEST_CASE(nv_serialize) std::vector{42, 666, 1024})); } +struct test_object { + std::uint64_t value{}; +}; + +template<> +struct bsd::nv_schema<::test_object> { + auto get() { + return (bsd::nv_literal("object type", "test object") + >> bsd::nv_field("value", &::test_object::value)); + } +}; + +TEST_CASE(nv_serialize_literal) +{ + auto obj = test_object{}; + auto nvl = bsd::nv_serialize(obj); + ATF_REQUIRE_EQ("test object", nvl.get_string("object type")); +} + +TEST_CASE(nv_deserialize_bad_literal) +{ + auto nvl = bsd::nv_list(); + nvl.add_number("value", 42u); + + auto obj = test_object{}; + ATF_REQUIRE_THROW(bsd::nv_key_not_found, + bsd::nv_deserialize(nvl, obj)); +} + ATF_INIT_TEST_CASES(tcs) { ATF_ADD_TEST_CASE(tcs, nv_encoder_bool); @@ -224,4 +254,6 @@ ATF_INIT_TEST_CASES(tcs) ATF_ADD_TEST_CASE(tcs, nv_encoder_optional); ATF_ADD_TEST_CASE(tcs, nv_serialize); + ATF_ADD_TEST_CASE(tcs, nv_serialize_literal); + ATF_ADD_TEST_CASE(tcs, nv_deserialize_bad_literal); } |
