From 7250a86b7eab2692d5c17d071436c84bac4574df Mon Sep 17 00:00:00 2001 From: "Claudius \"keldu\" Holeksa" Date: Thu, 29 Jun 2023 14:40:16 +0200 Subject: c++,codec-json: Implemented Tuple Decoding --- src/codec-json/json.tmpl.h | 62 +++++++++++++++++++++++++++++++++++++++++++++- 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 #include +#include + namespace saw { namespace impl { template @@ -468,7 +470,7 @@ struct json_decode...>, RootSchema, ToDeco constexpr static string_literal Literal = parameter_key_pack_type::literal; if(search_name == Literal.view()){ if(fields[i]){ - // TODO Change to this + // TODO Change to this. Maybe // return make_error(); return make_error(); } @@ -547,6 +549,8 @@ struct json_decode...>, RootSchema, ToDeco if(buff.read_composite_length() == 0){ return make_error(); } + + // Check if there are no elements present in the JSON Struct if(buff.read() == '}'){ if(sizeof...(T) > 0){ return make_error(); @@ -564,6 +568,62 @@ struct json_decode...>, RootSchema, ToDeco } }; +template +struct json_decode, RootSchema, ToDecode> { + template + static error_or decode_element(buffer_view& buff, data, ToDecode>& to){ + if constexpr (i < sizeof...(T)){ + if constexpr ( i > 0 ){ + if(buff.read() != ','){ + return make_error(); + } + buff.read_advance(1); + if(buff.read_composite_length() == 0){ + return make_error(); + } + } + using Type = typename parameter_pack_type::type; + + auto eov = json_decode::decode(buff, to.template get()); + if(eov.is_error()){ + return eov; + } + json_helper::skip_whitespace(buff); + if(buff.read_composite_length() == 0){ + return make_error(); + } + + eov = decode_element(buff, to); + if(eov.is_error()){ + return eov; + } + }else{ + if(buff.read() != ']'){ + return make_error(); + } + buff.read_advance(1); + } + return void_t{}; + } + + static error_or decode(buffer_view& buff, data, ToDecode>& to){ + assert(buff.read() == '['); + buff.read_advance(1); + + json_helper::skip_whitespace(buff); + if(buff.read_composite_length() == 0){ + return make_error(); + } + + 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 struct json_decode, 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 native_tup; data 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"){ -- cgit v1.2.3