diff options
-rw-r--r-- | modules/codec/c++/csv.h | 47 | ||||
-rw-r--r-- | modules/codec/c++/schema.h | 48 | ||||
-rw-r--r-- | modules/codec/c++/schema_factory.h | 3 | ||||
-rw-r--r-- | modules/codec/tests/csv.cpp | 50 |
4 files changed, 140 insertions, 8 deletions
diff --git a/modules/codec/c++/csv.h b/modules/codec/c++/csv.h index 67c2c1d..3727829 100644 --- a/modules/codec/c++/csv.h +++ b/modules/codec/c++/csv.h @@ -1,5 +1,7 @@ #pragma once +#include <forstio/error.h> + #include "data.h" namespace saw { @@ -7,8 +9,53 @@ namespace encode { struct Csv {}; } +namespace impl { +template<typename Schema, typename FromDecode> +struct csv_encode { + static_assert(always_false<T>, "Case not supported"); +}; + +template<typename T, size_t Dim> +struct csv_encode<schema::Array<T,Dim>, FromDecode> { + static_assert(Dim == 1, "Only one dimension is allowed."); + static_assert(!is_array<T>::value, "Array of an array is not allowed."); + static_assert(is_tuple<T>::value || is_struct<T>::value, "Only struct or tuples allowed inside a csv array"); + + using Schema = schema::Array<T,Dim>; + + static error_or<void> encode(const data<Schema, FromDecode>& from, data<Schema, encode::Csv>& to){ + if constexpr (is_struct<T>::value){ + auto eov = csv_encode<T>::encode_header(to); + if(eov.is_error()){ + return eov; + } + } + + for(std::size_t i = 0; i < from.size(); ++i){ + auto eov = csv_encode<T>::encode(from.at(i), to); + if(eov.is_error()){ + return eov; + } + } + + return void_t{}; + } +}; + +template<> +struct csv_encode<schema::String, FromDecode> { + using Schema = schema::String; + + static error_or<void> encode(const data<Schema, FromDecode>& from, data<Schema, encode::Csv>& to){ + + return void_t{}; + } +}; +} + template<typename Schema> class codec<Schema, encode::Csv> { + static_assert(is_array<Schema>::value, "Only an Array is allowed as a base value"); public: template<typename FromEncode> static error_or<void> encode(const data<Schema, FromEncode>& from, data<Schema,encode::Csv>& to){ diff --git a/modules/codec/c++/schema.h b/modules/codec/c++/schema.h index 69233fa..576f378 100644 --- a/modules/codec/c++/schema.h +++ b/modules/codec/c++/schema.h @@ -28,14 +28,6 @@ struct Union<Member<V, K>...> {}; template <typename T, size_t Dim = 1> struct Array {}; -template <class T> struct is_array { - constexpr static bool value = false; -}; - -template <class T, size_t Dim> struct is_array<schema::Array<T,Dim>> { - constexpr static bool value = true; -}; - template<typename T, size_t... S> struct FixedArray {}; template <typename... T> struct Tuple {}; @@ -55,6 +47,7 @@ class Wrapper {}; struct String {}; + struct SignedInteger {}; struct UnsignedInteger {}; struct FloatingPoint {}; @@ -106,4 +99,43 @@ struct Interface<Member<Function<Requests, Responses>,Names>...> {}; // NOLINTEND } // namespace schema +template <class T> struct is_struct { + constexpr static bool value = false; +}; + +template <class... V, string_literal... K> struct is_struct<schema::Struct<schema::Member<V,K>...>> { + constexpr static bool value = true; +}; + +template <class T> struct is_string { + constexpr static bool value = false; +}; + +template <> struct is_string<schema::String> { + constexpr static bool value = true; +}; + +template <class T> struct is_tuple { + constexpr static bool value = false; +}; + +template <class... T> struct is_tuple<schema::Tuple<T...>> { + constexpr static bool value = true; +}; + +template <class T> struct is_array { + constexpr static bool value = false; +}; + +template <class T, size_t Dim> struct is_array<schema::Array<T,Dim>> { + constexpr static bool value = true; +}; + +template <class T> struct is_primitive { + constexpr static bool value = false; +}; + +template <typename T, size_t N> struct is_primitive<schema::Primitive<T,N>> { + constexpr static bool value = true; +}; } // namespace saw diff --git a/modules/codec/c++/schema_factory.h b/modules/codec/c++/schema_factory.h index 91094fe..47185be 100644 --- a/modules/codec/c++/schema_factory.h +++ b/modules/codec/c++/schema_factory.h @@ -39,6 +39,9 @@ struct schema_factory<schema::Tuple<T...>> { } }; +/** + * This creates the base schema + */ template<typename T> constexpr schema_factory<T> build_schema() noexcept { return {}; diff --git a/modules/codec/tests/csv.cpp b/modules/codec/tests/csv.cpp new file mode 100644 index 0000000..507d4cb --- /dev/null +++ b/modules/codec/tests/csv.cpp @@ -0,0 +1,50 @@ +#include <forstio/test/suite.h> +#include "../c++/data.h" +#include "../c++/csv.h" + +#include <iostream> + +namespace { +namespace schema { +using namespace saw::schema; + +using ZeroDimArray = Array<Int32,0>; +using OneDimArray = Array<Int32,1>; +using TwoDimArray = Array<Int32,2>; +using ThreeDimArray = Array<Int32,3>; + +using TestStruct = Struct< + Member<String, "string">, + Member<UInt64, "number"> +>; + +using TestUnion = Union< + Member<TwoDimArray, "two_dim_array">, + Member<UInt64, "number"> +>; + +using TestTuple = Tuple< + TwoDimArray, + UInt64 +>; + +using TestInt32Pair = Tuple< + Int32, + Int32 +>; + +SAW_TEST("Codec Csv Encode Basic"){ + using namespace saw; + + data <TestStruct, encode::Native> native_data; + native_data.template get<"string">().set("foo"); + native_data.template get<"number">().set(140u); + + data <TestStruct, encode::Csv> csv_data; + codec<TestStruct, encode::Csv> csv_codec; + + auto eov = csv_codec.encode(native_data, csv_data); + SAW_EXPECT(eov.is_value(), "Couldn't encode data"); +} +} +} |