diff --git a/CMakeLists.txt b/CMakeLists.txt index 98d9944..4c1f5e9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,6 +31,11 @@ SOURCES cppm_examples_area() if(SERDEPP_BUILD_EXAMPLES) +cppm_target_define(serde_example2 BINARY +SOURCES + examples/example2.cpp +) + cppm_target_define(serde_example1 BINARY SOURCES examples/example1.cpp @@ -129,6 +134,10 @@ PUBLIC RapidJSON nlohmann_json toml11 yaml-cpp fmt magic_enum nameof) cppm_target_dependencies(serdepp ${serdepp_global_deps}) +cppm_target_dependencies(serde_example2 + ${serdepp_global_deps} + serdepp) + cppm_target_dependencies(serde_example1 ${serdepp_global_deps} serdepp) diff --git a/examples/example2.cpp b/examples/example2.cpp new file mode 100644 index 0000000..5d7c77a --- /dev/null +++ b/examples/example2.cpp @@ -0,0 +1,100 @@ +#include +#include +#include +#include +#include +#include "serdepp/adaptor/rapidjson.hpp" +#include + +enum class tenum {INPUT, OUTPUT, INPUT_2 , OUTPUT_2 }; + +struct nested { + std::string version; + std::string desc; + std::optional opt_desc; +}; +DERIVE_SERDE_NON_INTRUSIVE(nested, + (&Self::version, "version", value_or_struct) + (&Self::opt_desc ,"opt_desc") + [attributes(default_{"default value"})] + (&Self::desc ,"desc") + .no_remain()) + +class test { +public: + std::optional str; + int i; + std::optional> vec; + tenum io; + std::vector in; + std::map m; + std::map nm; + std::string pri; +}; +DERIVE_SERDE_NON_INTRUSIVE(test, + [attributes(default_{"hello"})] + (&Self::str, "str") + (&Self::i, "i") + (&Self::vec, "vec") + [attributes(default_{tenum::OUTPUT}, to_lower, under_to_dash)] + (&Self::io, "io") + [attributes(make_optional)] + (&Self::in, "in") + [attributes(to_upper, under_to_dash)] + (&Self::pri, "pri") + (&Self::m , "m") + (&Self::nm , "nm")) + +int main() +{ + nlohmann::json v = R"({ + "i": 10, + "vec": [ "one", "two", "three" ], + "io" : "OUTPUT-2", + "pri" : "PRi-FF", + "in" : [{ "version" : "hello" }, "single"], + "m" : { "a" : "1", + "b" : "2", + "c" : "3" }, + "nm" : { "a" : {"version" : "hello" }, + "b" : "hello2" } + })"_json; + + // try { + + test t = serde::deserialize(v); + fmt::print("{}\n",serde::to_str(t.io)); + + YAML::Node y = serde::serialize(10); + std::cout << y << "\n"; + serde::deserialize(y); + + + auto v_to_json = serde::serialize(t); + auto v_to_toml = serde::serialize(t); + auto v_to_yaml = serde::serialize(t); + auto v_to_rjson = serde::serialize(t); + auto print = [](auto& doc) { + using namespace rapidjson; + StringBuffer buffer; + Writer writer(buffer); + doc.Accept(writer); + std::cout << "doc:" << buffer.GetString() << std::endl; + }; + + std::cout << "toml: " << v_to_toml << std::endl; + fmt::print("json: {}\n", v_to_json.dump()); + std::cout << "yaml: " << v_to_yaml << std::endl; + print(v_to_rjson); + + test t_from_toml = serde::deserialize(v_to_toml); + test t_from_yaml = serde::deserialize(v_to_yaml); + test t_from_rjson = serde::deserialize(v_to_rjson); + + fmt::print("{}\n", t_from_toml); + fmt::print("{}\n", t_from_yaml); + fmt::print("{}\n", t_from_rjson); + std::cout << t << '\n'; + + return 0; +} diff --git a/include/serdepp/utility.hpp b/include/serdepp/utility.hpp index 975e674..0307e14 100644 --- a/include/serdepp/utility.hpp +++ b/include/serdepp/utility.hpp @@ -24,6 +24,34 @@ __VA_ARGS__; \ } \ +#define DERIVE_SERDE_NON_INTRUSIVE(Type, ...) \ +namespace serde { \ + using namespace attribute; \ + template \ + struct serde_serializer { \ + using Adaptor = typename serde_ctx::Adaptor; \ + constexpr inline static auto from(serde_ctx& ctx, Type& data, std::string_view key) { \ + serde_struct ss(ctx, data); \ + using Self [[maybe_unused]] = Type; \ + ss \ + __VA_ARGS__; \ + ctx.read(); \ + }\ +\ + constexpr inline static auto into(serde_ctx& ctx, const Type& data, std::string_view key) { \ + auto struct_ctx = serde_context(ctx.adaptor); \ + serde_struct ss(struct_ctx, const_cast(data)); \ + using Self [[maybe_unused]] = Type; \ + ss \ + __VA_ARGS__; \ + ctx.read(); \ + } \ + }; \ + namespace meta { \ + template struct is_serdeable : std::true_type {}; \ + } \ +} + #define _SF_(name) (&Self::name, #name) #endif