summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudius "keldu" Holeksa <mail@keldu.de>2023-06-29 14:40:16 +0200
committerClaudius "keldu" Holeksa <mail@keldu.de>2023-06-29 14:40:16 +0200
commit7250a86b7eab2692d5c17d071436c84bac4574df (patch)
tree35598c441ce7985425ff787e59bdba2437a3ff09
parentdd5d61330032511f5b0e05e813bbfe2054841f5d (diff)
c++,codec-json: Implemented Tuple Decoding
-rw-r--r--src/codec-json/json.tmpl.h62
-rw-r--r--tests/codec-json.cpp9
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"){