Skip to content

Commit

Permalink
Add non-intrusive flavour of DERIVE_SERDE
Browse files Browse the repository at this point in the history
  • Loading branch information
seingierbpk committed Dec 28, 2023
1 parent 2682b8d commit 30047e1
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 0 deletions.
9 changes: 9 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down
100 changes: 100 additions & 0 deletions examples/example2.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
#include <serdepp/serde.hpp>
#include <serdepp/adaptor/nlohmann_json.hpp>
#include <serdepp/adaptor/toml11.hpp>
#include <serdepp/adaptor/fmt.hpp>
#include <serdepp/adaptor/yaml-cpp.hpp>
#include "serdepp/adaptor/rapidjson.hpp"
#include <memory>

enum class tenum {INPUT, OUTPUT, INPUT_2 , OUTPUT_2 };

struct nested {
std::string version;
std::string desc;
std::optional<std::string> 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<std::string> str;
int i;
std::optional<std::vector<std::string>> vec;
tenum io;
std::vector<nested> in;
std::map<std::string, std::string> m;
std::map<std::string, nested> 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<test>(v);
fmt::print("{}\n",serde::to_str(t.io));

YAML::Node y = serde::serialize<YAML::Node>(10);
std::cout << y << "\n";
serde::deserialize<int>(y);


auto v_to_json = serde::serialize<nlohmann::json>(t);
auto v_to_toml = serde::serialize<serde::toml_v>(t);
auto v_to_yaml = serde::serialize<serde::yaml>(t);
auto v_to_rjson = serde::serialize<rapidjson::Document>(t);
auto print = [](auto& doc) {
using namespace rapidjson;
StringBuffer buffer;
Writer<StringBuffer> 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<test>(v_to_toml);
test t_from_yaml = serde::deserialize<test>(v_to_yaml);
test t_from_rjson = serde::deserialize<test>(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;
}
28 changes: 28 additions & 0 deletions include/serdepp/utility.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,34 @@
__VA_ARGS__; \
} \

#define DERIVE_SERDE_NON_INTRUSIVE(Type, ...) \
namespace serde { \
using namespace attribute; \
template<typename serde_ctx> \
struct serde_serializer<Type, serde_ctx> { \
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<Adaptor, true>(ctx.adaptor); \
serde_struct ss(struct_ctx, const_cast<Type&>(data)); \
using Self [[maybe_unused]] = Type; \
ss \
__VA_ARGS__; \
ctx.read(); \
} \
}; \
namespace meta { \
template<class Context> struct is_serdeable<Context, Type, void> : std::true_type {}; \
} \
}

#define _SF_(name) (&Self::name, #name)

#endif

0 comments on commit 30047e1

Please sign in to comment.