Skip to content

Add non-intrusive flavour of DERIVE_SERDE #59

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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