aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libnvxx/nvxx_serialize.h71
-rw-r--r--libnvxx/tests/nvxx_serialize.cc34
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);
}