diff options
Diffstat (limited to 'modules/codec-json/c++/json.tmpl.hpp')
-rw-r--r-- | modules/codec-json/c++/json.tmpl.hpp | 120 |
1 files changed, 75 insertions, 45 deletions
diff --git a/modules/codec-json/c++/json.tmpl.hpp b/modules/codec-json/c++/json.tmpl.hpp index 11eba49..748f2c2 100644 --- a/modules/codec-json/c++/json.tmpl.hpp +++ b/modules/codec-json/c++/json.tmpl.hpp @@ -7,6 +7,34 @@ namespace saw { namespace impl { +struct json_helper { + static bool is_whitespace(int8_t ch) { + return ch == '\t' || ch == ' ' || ch == '\r' || ch == '\n'; + } + + static void skip_whitespace(buffer_view& buff) { + while(buff.read_composite_length() > 0 && json_helper::is_whitespace(buff.read())) { + buff.read_advance(1); + } + } + + static error_or<void> print_pretty_indent(buffer& to, uint64_t depth){ + { + auto eov = to.push(*reinterpret_cast<const uint8_t*>("\r\n"), 2); + if(!eov.template is_type<err::no_error>()){ + return eov; + } + } + for(uint64_t ind = 0; ind < depth; ++ind){ + auto eov_ele = to.push('\t'); + if(!eov_ele.template is_type<err::no_error>()){ + return eov_ele; + } + } + return void_t{}; + } +}; + template<typename Schema, typename FromEncode> class json_encode { static_assert(always_false<Schema, FromEncode>, "This schema type is not being handled by the json encoding."); @@ -16,7 +44,7 @@ template<typename T, size_t N, typename FromEncode> struct json_encode<schema::Primitive<T,N>, FromEncode> { using Schema = schema::Primitive<T,N>; - static error_or<void> encode(const data<Schema, FromEncode>& from, buffer& to) { + static error_or<void> encode(const data<Schema, FromEncode>& from, buffer& to, uint64_t, bool) { auto val = from.get(); std::array<uint8_t, 256> data; auto tc_result = std::to_chars(reinterpret_cast<char*>(data.data()), reinterpret_cast<char*>(data.data())+data.size(), val); @@ -49,7 +77,7 @@ template<typename FromEncode> struct json_encode<schema::String, FromEncode> { using Schema = schema::String; - static error_or<void> encode(const data<schema::String, FromEncode>& from, buffer& to) { + static error_or<void> encode(const data<schema::String, FromEncode>& from, buffer& to, uint64_t, bool) { { auto err = to.push('"'); if(!err.template is_type<err::no_error>()){ @@ -78,11 +106,19 @@ struct json_encode<schema::Tuple<T...>, FromEncode> { using Schema = schema::Tuple<T...>; template<size_t i> - static error_or<void> encode_element(const data<schema::Tuple<T...>, FromEncode>& from, buffer& to){ - auto eov = json_encode<typename parameter_pack_type<i, T...>::type, FromEncode>::encode(from.template get<i>(), to); + static error_or<void> encode_element(const data<schema::Tuple<T...>, FromEncode>& from, buffer& to, uint64_t depth, bool pretty){ + if(pretty){ + auto eov = json_helper::print_pretty_indent(to, depth); + if(eov.is_error()){ + return eov; + } + } + { + auto eov = json_encode<typename parameter_pack_type<i, T...>::type, FromEncode>::encode(from.template get<i>(), to, depth, pretty); - if(eov.is_error()){ - return eov; + if(eov.is_error()){ + return eov; + } } if constexpr ( (i+1) < sizeof...(T)){ @@ -93,26 +129,31 @@ struct json_encode<schema::Tuple<T...>, FromEncode> { } } { - auto eov_ele = encode_element<i+1>(from, to); + auto eov_ele = encode_element<i+1>(from, to, depth, pretty); if(eov_ele.is_error()){ return eov_ele; } } - - } return void_t{}; } - static error_or<void> encode(const data<Schema, FromEncode>& from, buffer& to) { + static error_or<void> encode(const data<Schema, FromEncode>& from, buffer& to, uint64_t depth, bool pretty) { { + auto err = to.push('['); if(!err.template is_type<err::no_error>()){ return err; } } if constexpr ( sizeof...(T) > 0 ){ - auto eov = encode_element<0>(from, to); + auto eov = encode_element<0>(from, to, depth+1u, pretty); + if(eov.is_error()){ + return eov; + } + } + if(pretty){ + auto eov = json_helper::print_pretty_indent(to, depth); if(eov.is_error()){ return eov; } @@ -133,9 +174,9 @@ struct json_encode<schema::Array<T,D>, FromEncode> { using Schema = schema::Array<T,D>; template<size_t Level> - static error_or<void> encode_level(const data<Schema, FromEncode>& from, buffer& to, std::array<std::size_t, D>& index){ + static error_or<void> encode_level(const data<Schema, FromEncode>& from, buffer& to, std::array<std::size_t, D>& index, uint64_t depth, bool pretty){ if constexpr (Level == D){ - auto eov = json_encode<T, FromEncode>::encode(from.at(index), to); + auto eov = json_encode<T, FromEncode>::encode(from.at(index), to, depth, pretty); if(eov.is_error()){ return eov; } @@ -155,7 +196,7 @@ struct json_encode<schema::Array<T,D>, FromEncode> { } { index[Level] = i; - auto eov = encode_level<Level+1>(from, to, index); + auto eov = encode_level<Level+1>(from, to, index, depth, pretty); if(eov.is_error()){ return eov; } @@ -171,9 +212,9 @@ struct json_encode<schema::Array<T,D>, FromEncode> { return void_t{}; } - static error_or<void> encode(const data<Schema, FromEncode>& from, buffer& to) { + static error_or<void> encode(const data<Schema, FromEncode>& from, buffer& to, uint64_t depth, bool pretty) { std::array<std::size_t, D> index; - return encode_level<0>(from, to, index); + return encode_level<0>(from, to, index, depth, pretty); } }; @@ -181,8 +222,8 @@ template<typename T, size_t... D, typename FromEncode> struct json_encode<schema::FixedArray<T,D...>, FromEncode> { using Schema = schema::FixedArray<T,D...>; - static error_or<void> encode_at(const data<Schema, FromEncode>& from, buffer& to, std::array<std::size_t, sizeof...(D)>& index){ - auto eov = json_encode<T, FromEncode>::encode(from.at(index), to); + static error_or<void> encode_at(const data<Schema, FromEncode>& from, buffer& to, std::array<std::size_t, sizeof...(D)>& index, uint64_t depth, bool pretty){ + auto eov = json_encode<T, FromEncode>::encode(from.at(index), to, depth, pretty); if(eov.is_error()){ return eov; } @@ -190,7 +231,7 @@ struct json_encode<schema::FixedArray<T,D...>, FromEncode> { } template<size_t Level, size_t Dim, size_t... DimPack> - static error_or<void> encode_level(const data<Schema, FromEncode>& from, buffer& to, std::array<std::size_t, sizeof...(D)>& index){ + static error_or<void> encode_level(const data<Schema, FromEncode>& from, buffer& to, std::array<std::size_t, sizeof...(D)>& index, uint64_t depth, bool pretty){ { auto err = to.push('['); if(!err.template is_type<err::no_error>()){ @@ -207,12 +248,12 @@ struct json_encode<schema::FixedArray<T,D...>, FromEncode> { { index[Level] = i; if constexpr (sizeof...(DimPack) > 0){ - auto eov = encode_level<Level+1, DimPack...>(from, to, index); + auto eov = encode_level<Level+1, DimPack...>(from, to, index, depth, pretty); if(eov.is_error()){ return eov; } }else{ - auto eov = encode_at(from,to,index); + auto eov = encode_at(from,to,index,depth,pretty); if(eov.is_error()){ return eov; } @@ -228,10 +269,10 @@ struct json_encode<schema::FixedArray<T,D...>, FromEncode> { return void_t{}; } - static error_or<void> encode(const data<Schema, FromEncode>& from, buffer& to) { + static error_or<void> encode(const data<Schema, FromEncode>& from, buffer& to, uint64_t depth, bool pretty) { if constexpr (sizeof...(D) > 0){ std::array<std::size_t, sizeof...(D)> index; - return encode_level<0,D...>(from, to, index); + return encode_level<0,D...>(from, to, index, depth+1u, pretty); } return void_t{}; } @@ -242,7 +283,7 @@ struct json_encode<schema::Struct<schema::Member<T,Key>...>, FromEncode> { using Schema = schema::Struct<schema::Member<T,Key>...>; template<size_t i> - static error_or<void> encode_element(const data<Schema, FromEncode>& from, buffer& to){ + static error_or<void> encode_element(const data<Schema, FromEncode>& from, buffer& to, uint64_t depth, bool pretty){ // Encode the name { std::string_view view = parameter_key_pack_type<i, Key...>::literal.view(); @@ -268,7 +309,7 @@ struct json_encode<schema::Struct<schema::Member<T,Key>...>, FromEncode> { } // Encode the value - auto eov = json_encode<typename parameter_pack_type<i, T...>::type, FromEncode>::encode(from.template get<parameter_key_pack_type<i, Key...>::literal>(), to); + auto eov = json_encode<typename parameter_pack_type<i, T...>::type, FromEncode>::encode(from.template get<parameter_key_pack_type<i, Key...>::literal>(), to, depth, pretty); // Go to the next element if constexpr ( (i+1) < sizeof...(T)){ @@ -279,7 +320,7 @@ struct json_encode<schema::Struct<schema::Member<T,Key>...>, FromEncode> { } } { - auto eov_ele = encode_element<i+1>(from, to); + auto eov_ele = encode_element<i+1>(from, to, depth, pretty); if(eov_ele.is_error()){ return eov_ele; } @@ -290,7 +331,7 @@ struct json_encode<schema::Struct<schema::Member<T,Key>...>, FromEncode> { return void_t{}; } - static error_or<void> encode(const data<Schema, FromEncode>& from, buffer& to) { + static error_or<void> encode(const data<Schema, FromEncode>& from, buffer& to, uint64_t depth, bool pretty) { { auto err = to.push('{'); if(!err.template is_type<err::no_error>()){ @@ -298,7 +339,7 @@ struct json_encode<schema::Struct<schema::Member<T,Key>...>, FromEncode> { } } if constexpr ( sizeof...(T) > 0 ){ - auto eov = encode_element<0>(from, to); + auto eov = encode_element<0>(from, to, depth, pretty); if(eov.is_error()){ return eov; } @@ -319,7 +360,7 @@ struct json_encode<schema::Union<schema::Member<T,Key>...>, FromEncode> { using Schema = schema::Union<schema::Member<T,Key>...>; template<size_t i> - static error_or<void> encode_element(const data<Schema, FromEncode>& from, buffer& to){ + static error_or<void> encode_element(const data<Schema, FromEncode>& from, buffer& to, uint64_t depth, bool pretty){ if(from.template holds_alternative<parameter_key_pack_type<i, Key...>::literal>()){ // Encode the name { @@ -346,12 +387,12 @@ struct json_encode<schema::Union<schema::Member<T,Key>...>, FromEncode> { } // Encode the value - auto eov = json_encode<typename parameter_pack_type<i, T...>::type, FromEncode>::encode(from.template get<parameter_key_pack_type<i, Key...>::literal>(), to); + auto eov = json_encode<typename parameter_pack_type<i, T...>::type, FromEncode>::encode(from.template get<parameter_key_pack_type<i, Key...>::literal>(), to, depth, pretty); } // Go to the next element if constexpr ( (i+1) < sizeof...(T)){ { - auto eov_ele = encode_element<i+1>(from, to); + auto eov_ele = encode_element<i+1>(from, to, depth, pretty); if(eov_ele.is_error()){ return eov_ele; } @@ -362,7 +403,7 @@ struct json_encode<schema::Union<schema::Member<T,Key>...>, FromEncode> { return void_t{}; } - static error_or<void> encode(const data<Schema, FromEncode>& from, buffer& to) { + static error_or<void> encode(const data<Schema, FromEncode>& from, buffer& to, uint64_t depth, bool pretty) { { auto err = to.push('{'); if(!err.template is_type<err::no_error>()){ @@ -370,7 +411,7 @@ struct json_encode<schema::Union<schema::Member<T,Key>...>, FromEncode> { } } if constexpr ( sizeof...(T) > 0 ){ - auto eov = encode_element<0>(from, to); + auto eov = encode_element<0>(from, to, depth, pretty); if(eov.is_error()){ return eov; } @@ -386,18 +427,6 @@ struct json_encode<schema::Union<schema::Member<T,Key>...>, FromEncode> { } }; -struct json_helper { - static bool is_whitespace(int8_t ch) { - return ch == '\t' || ch == ' ' || ch == '\r' || ch == '\n'; - } - - static void skip_whitespace(buffer_view& buff) { - while(buff.read_composite_length() > 0 && json_helper::is_whitespace(buff.read())) { - buff.read_advance(1); - } - } -}; - template<typename Schema, typename ToDecode> struct json_decode; @@ -667,6 +696,7 @@ struct json_decode<schema::Tuple<T...>, ToDecode> { return make_error<err::invalid_state>(); } buff.read_advance(1); + json_helper::skip_whitespace(buff); if(buff.read_composite_length() == 0){ return make_error<err::buffer_exhausted>(); } |