diff options
-rw-r--r-- | src/codec-json/json.tmpl.h | 62 | ||||
-rw-r--r-- | tests/codec-json.cpp | 9 |
2 files changed, 69 insertions, 2 deletions
diff --git a/src/codec-json/json.tmpl.h b/src/codec-json/json.tmpl.h index 6cf7189..3d3ad91 100644 --- a/src/codec-json/json.tmpl.h +++ b/src/codec-json/json.tmpl.h @@ -3,6 +3,8 @@ #include <charconv> #include <sstream> +#include <iostream> + namespace saw { namespace impl { template<typename Schema, typename RootSchema, typename FromEncode> @@ -468,7 +470,7 @@ struct json_decode<schema::Struct<schema::Member<T,Lits>...>, RootSchema, ToDeco constexpr static string_literal Literal = parameter_key_pack_type<i, Lits...>::literal; if(search_name == Literal.view()){ if(fields[i]){ - // TODO Change to this + // TODO Change to this. Maybe // return make_error<err::already_exists>(); return make_error<err::invalid_state>(); } @@ -547,6 +549,8 @@ struct json_decode<schema::Struct<schema::Member<T,Lits>...>, RootSchema, ToDeco if(buff.read_composite_length() == 0){ return make_error<err::buffer_exhausted>(); } + + // Check if there are no elements present in the JSON Struct if(buff.read() == '}'){ if(sizeof...(T) > 0){ return make_error<err::invalid_state>(); @@ -564,6 +568,62 @@ struct json_decode<schema::Struct<schema::Member<T,Lits>...>, RootSchema, ToDeco } }; +template<typename... T, typename RootSchema, typename ToDecode> +struct json_decode<schema::Tuple<T...>, RootSchema, ToDecode> { + template<std::size_t i> + static error_or<void> decode_element(buffer_view& buff, data<schema::Tuple<T...>, ToDecode>& to){ + if constexpr (i < sizeof...(T)){ + if constexpr ( i > 0 ){ + if(buff.read() != ','){ + return make_error<err::invalid_state>(); + } + buff.read_advance(1); + if(buff.read_composite_length() == 0){ + return make_error<err::buffer_exhausted>(); + } + } + using Type = typename parameter_pack_type<i, T...>::type; + + auto eov = json_decode<Type, RootSchema, ToDecode>::decode(buff, to.template get<i>()); + if(eov.is_error()){ + return eov; + } + json_helper::skip_whitespace(buff); + if(buff.read_composite_length() == 0){ + return make_error<err::buffer_exhausted>(); + } + + eov = decode_element<i+1>(buff, to); + if(eov.is_error()){ + return eov; + } + }else{ + if(buff.read() != ']'){ + return make_error<err::invalid_state>(); + } + buff.read_advance(1); + } + return void_t{}; + } + + static error_or<void> decode(buffer_view& buff, data<schema::Tuple<T...>, ToDecode>& to){ + assert(buff.read() == '['); + buff.read_advance(1); + + json_helper::skip_whitespace(buff); + if(buff.read_composite_length() == 0){ + return make_error<err::buffer_exhausted>(); + } + + auto eov = decode_element<0>(buff, to); + if(eov.is_error()){ + return eov; + } + + return void_t{}; + } +}; + // The whole std::vector approach is hacky af. ToDo change it maybe? template<typename T, size_t D, typename RootSchema, typename ToDecode> struct json_decode<schema::Array<T,D>, RootSchema, ToDecode> { diff --git a/tests/codec-json.cpp b/tests/codec-json.cpp index 926f550..e1b8b5c 100644 --- a/tests/codec-json.cpp +++ b/tests/codec-json.cpp @@ -213,7 +213,7 @@ SAW_TEST("String write and read"){ SAW_EXPECT(nat_str == "foo", "Incorrect value decoded"); } -SAW_TEST("Tuple write"){ +SAW_TEST("Tuple read and write"){ using namespace saw; data<schema::TestTuple, encode::Native> native_tup; data<schema::TestTuple, encode::Json> json_tup; @@ -233,6 +233,13 @@ SAW_TEST("Tuple write"){ std::string enc_val = convert_to_string(json_tup.get_buffer()); SAW_EXPECT(enc_val == str_v, std::string{"Tuple not encoded correctly. Encoded: "} + enc_val + std::string{" Expected: "} + std::string{str_v}); + native_tup = {}; + + eov = json_codec.decode(json_tup, native_tup); + SAW_EXPECT(eov.is_value(), "Decoding error"); + + SAW_EXPECT(native_tup.template get<0>() == "bar", "Invalid Value 0"); + SAW_EXPECT(native_tup.template get<1>().get() == 34, "Invalid Value 1"); } SAW_TEST("Array write"){ |