Throw on missing non-optional object key

This commit is contained in:
G.H.O.S.T 2024-12-27 01:38:37 +01:00
parent 67112e3983
commit 4cbc64a7a4
Signed by: G.H.O.S.T
GPG Key ID: 3BD93EABD1407B82

View File

@ -3,6 +3,7 @@
#include <code/json/optional.hxx> #include <code/json/optional.hxx>
#include <code/json/pointer.hxx> #include <code/json/pointer.hxx>
#include <code/json/traits.hxx>
#include <code/json/variant.hxx> #include <code/json/variant.hxx>
#include <chrono> #include <chrono>
@ -41,11 +42,17 @@ namespace code::json
std::copy_n(str, N, name); std::copy_n(str, N, name);
} }
operator std::string const() const std::string const
str() const
{ {
return name; return name;
} }
operator std::string const() const
{
return str();
}
char name[N]; char name[N];
}; };
@ -67,6 +74,10 @@ namespace code::json
using T = member_traits<decltype(Member)>::class_type; using T = member_traits<decltype(Member)>::class_type;
using M = member_traits<decltype(Member)>::member_type; using M = member_traits<decltype(Member)>::member_type;
static constexpr bool is_optional{
is_optional_v<M>
};
static static
void void
marshal(variant& v, T const& instance, marshaling_context_t* context) marshal(variant& v, T const& instance, marshaling_context_t* context)
@ -78,11 +89,22 @@ namespace code::json
void void
unmarshal(T& instance, variant const& v, marshaling_context_t* context) unmarshal(T& instance, variant const& v, marshaling_context_t* context)
{ {
if (!v.contains(Name.str())) {
if (is_optional) {
return;
}
throw std::runtime_error{"missing field '" + Name.str() + "'"};
}
instance.*Member = marshaling_traits<M>::unmarshal(v.get(Name), context); instance.*Member = marshaling_traits<M>::unmarshal(v.get(Name), context);
} }
struct pointer_t struct pointer_t
{ {
using T = member_traits<decltype(Member)>::class_type;
using M = member_traits<decltype(Member)>::member_type;
static pointer const& static pointer const&
ptr() ptr()
{ {
@ -104,6 +126,10 @@ namespace code::json
auto ptr_v = ptr().read(v); auto ptr_v = ptr().read(v);
if (!ptr_v) { if (!ptr_v) {
if (is_optional) {
return;
}
throw std::runtime_error{ "missing field '" + to_string(ptr()) + "'" }; throw std::runtime_error{ "missing field '" + to_string(ptr()) + "'" };
} }