Skip to content

Commit

Permalink
Merge pull request #43 from injae/dev
Browse files Browse the repository at this point in the history
serde_type_checker default define update

new feature reflection 
mem_get() from member name
mem_get() from index
  • Loading branch information
injae authored Dec 15, 2021
2 parents 21677fb + 63984a6 commit 1ec0fd1
Show file tree
Hide file tree
Showing 13 changed files with 188 additions and 18 deletions.
10 changes: 10 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ SOURCES
examples/sugar.cpp
)

cppm_target_define(reflection BINARY
SOURCES
examples/reflection.cpp
)

cppm_target_define(print BINARY
SOURCES
examples/print.cpp
Expand Down Expand Up @@ -135,6 +140,10 @@ cppm_target_dependencies(sugar
${serdepp_global_deps}
serdepp)

cppm_target_dependencies(reflection
${serdepp_global_deps}
serdepp)

cppm_target_dependencies(print
${serdepp_global_deps}
serdepp)
Expand Down Expand Up @@ -165,6 +174,7 @@ cppm_target_install(variant_example)
cppm_target_install(parse_file_example)
cppm_target_install(struct_attribute_example)
cppm_target_install(sugar)
cppm_target_install(reflection)
cppm_target_install(print)
cppm_target_install(pointer)

5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ c++17 low cost serialize deserialize adaptor library like rust serde.rs
- [x] [attributes](#Attributes) and custom attribute support (value_or_struct, default, multi_key ...)
- [x] variant support (std::variant<int, std::vector<...>, UserType, EnumType...>) [example](examples/variant.cpp)
- [x] pointer support (T*, std::shared_ptr<T>, std::unique_ptr<T>)
- [x] reflection support (BETA) (mem_get(member_name) or mem_get<index>())

## Serdepp Strcuture
![Serdepp structure](Serdepp_Structure.png)
Expand Down Expand Up @@ -65,12 +66,12 @@ int main() {
ex.number_ = 1024;
ex.vec_ = {"a", "b", "c"};
ex.tenum_ = t_enum::B;
//std::cout << ex << "\n";

nlohmann::json json_from_ex = serde::serialize<nlohmann::json>(ex);
example ex_from_json = serde::deserialize<example>(json_from_ex);

fmt::print("json:{}\n",json_from_ex.dump(4));

std::cout << "json: " << json_from_ex.dump(4) << "\n";
fmt::print("fmt:{}\n",ex_from_json);
}

Expand Down
8 changes: 8 additions & 0 deletions cppm.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@
name = "sugar"
source = ["examples/sugar.cpp"]

[[example]]
name = "reflection"
source = ["examples/reflection.cpp"]

[[example]]
name = "print"
source = ["examples/print.cpp"]
Expand All @@ -53,6 +57,10 @@
name = "pointer"
source = ["examples/pointer.cpp"]

#[[example]]
# name = "tuple_sort"
# source = ["examples/tuple_sort.cpp"]

#[[example]]
# name = "sol2_example"
# source = ["examples/sol2.cpp"]
Expand Down
3 changes: 1 addition & 2 deletions examples/example.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
#include "serdepp/adaptor/rapidjson.hpp"
#include <memory>

using namespace serde::ostream;

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


Expand All @@ -16,6 +14,7 @@ struct nested {
(&Self::version, "version", value_or_struct)
(&Self::opt_desc ,"opt_desc")
[attributes(default_{"default value"})]

(&Self::desc ,"desc")
.no_remain())
std::string version;
Expand Down
2 changes: 1 addition & 1 deletion examples/print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ int main(int argc, char *argv[])

auto j_flatten = serde::deserialize<std::vector<Test>>(jflat);

std::cout << serde::serialize<serde::serde_sstream>(j_flatten).str();
std::cout << serde::to_string(j_flatten) << "\n";

return 0;
}
22 changes: 22 additions & 0 deletions examples/reflection.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#include <serdepp/serde.hpp>
#include <serdepp/adaptor/reflection.hpp>

struct Test {
DERIVE_SERDE(Test,
(&Self::test, "test")
(&Self::str, "str"))
int test;
std::string str;
};

int main(int argc, char *argv[])
{
auto t = Test{1,"hello"};
std:: cout << t << "\n";
serde::mem_get<std::string>(t, "str") = "why";
serde::mem_get<int, 0>(t) = 200;
std:: cout << t << "\n";

return 0;
}

6 changes: 3 additions & 3 deletions examples/sugar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ namespace serde::attribute {
}
};
}
constexpr static auto tttt = detail::tttt{};
[[maybe_unused]] constexpr static auto tttt = detail::tttt{};
}


struct Test {
DERIVE_SERDE(Test,
[attributes(flatten, default_(""))]
[attributes(flatten)]
(&Self::test, "test")
[attributes(flatten, default_(""))]
(&Self::str, "str"))
Expand All @@ -35,7 +35,7 @@ struct Test {

int main(int argc, char *argv[])
{
fmt::print("{}\n",Test{1});
std::cout << Test{1} << "\n";

return 0;
}
1 change: 1 addition & 0 deletions examples/variant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ int main() {

fmt::print("------\n");
auto j_flatten = deserialize<std::vector<Test>>(jflat);
fmt::print("------\n");
auto j_none = deserialize<std::vector<Test>>(j);
fmt::print("{}\n",serialize<nlohmann::json>(j_flatten).dump(4));
fmt::print("{}\n",serialize<nlohmann::json>(j_none).dump(4));
Expand Down
116 changes: 116 additions & 0 deletions include/serdepp/adaptor/reflection.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
#pragma once

#ifndef __SERDEPP_ADAPTOR_RFLECTION_HPP__
#define __SERDEPP_ADAPTOR_RFLECTION_HPP__

#include <serdepp/serde.hpp>
#include <string_view>

namespace serde {
template<class T>
struct reflect_from_name {
//DERIVE_SERDE(reflect<T>,(&Self::key, "key")(&Self::member, "member"))
reflect_from_name() = default;
reflect_from_name(std::string_view member) : key(member) {}
std::string_view key;
T* member = nullptr;
};

template<class T, size_t idx>
struct reflect_from_index {
constexpr static size_t find_idx = idx;
//DERIVE_SERDE(reflect<T>,(&Self::key, "key")(&Self::member, "member"))
reflect_from_index() = default;
size_t index = 0;
T* member = nullptr;
};

template<class T>
struct serde_adaptor_helper<reflect_from_name<T>> : derive_serde_adaptor_helper<reflect_from_name<T>> {
inline constexpr static bool is_null(reflect_from_name<T> &adaptor, std::string_view key) { return false; }
inline constexpr static size_t size(reflect_from_name<T> &adaptor) { return 1; }
inline constexpr static bool is_struct(reflect_from_name<T> &adaptor) { return true; }
};

template<class T, size_t idx>
struct serde_adaptor_helper<reflect_from_index<T,idx>> : derive_serde_adaptor_helper<reflect_from_index<T, idx>> {
inline constexpr static bool is_null(reflect_from_index<T, idx> &adaptor, std::string_view key) { return false; }
inline constexpr static size_t size(reflect_from_index<T, idx> &adaptor) { return 1; }
inline constexpr static bool is_struct(reflect_from_index<T, idx> &adaptor) { return true; }
};

template<typename U, typename T>
struct serde_adaptor<reflect_from_name<U>, T, std::enable_if_t<std::is_same_v<U, remove_cvref_t<T>>>> {
constexpr static void from(reflect_from_name<U>& s, std::string_view key, T& data){
if(key == s.key) {
s.member = &data;
}
}
static void into(reflect_from_name<U>& s, std::string_view key, const T& data) {
throw serde::unimplemented_error("serde_adaptor<reflect_from_name>::into(reflect_from_name, key, data)");
}
};

template<typename U, typename T>
struct serde_adaptor<reflect_from_name<U>, T , std::enable_if_t<!std::is_same_v<U, remove_cvref_t<T>>>> {
static void from(reflect_from_name<U>& s, std::string_view key, T& data){
if(key == s.key) {
std::string error = std::string(nameof::nameof_type<U>());
throw serde::type_error(error + " != " + std::string(nameof::nameof_type<remove_cvref_t<T>>()));
}
}
static void into(reflect_from_name<U>& s, std::string_view key, const T& data) {
throw serde::unimplemented_error("serde_adaptor<reflect_from_name>::into(reflect_from_name, key, data)");
}
};

template<typename U, typename T, size_t index>
struct serde_adaptor<reflect_from_index<U, index>, T, std::enable_if_t<std::is_same_v<U, remove_cvref_t<T>>>> {
constexpr static void from(reflect_from_index<U, index>& s, std::string_view key, T& data){
if(s.index == s.find_idx) {
s.member = &data;
}
s.index++;
}
static void into(reflect_from_index<U,index>& s, std::string_view key, const T& data) {
throw serde::unimplemented_error("serde_adaptor<reflect_from_name>::into(reflect_from_name, key, data)");
}
};

template<typename U, typename T, size_t index>
struct serde_adaptor<reflect_from_index<U, index>, T, std::enable_if_t<!std::is_same_v<U, remove_cvref_t<T>>>> {
static void from(reflect_from_index<U, index>& s, std::string_view key, T& data){
if(s.index == s.find_idx) {
std::string error = std::string(nameof::nameof_type<U>());
throw serde::type_error(error + " != " + std::string(nameof::nameof_type<remove_cvref_t<T>>()));
}
s.index++;
}
static void into(reflect_from_index<U,index>& s, std::string_view key, const T& data) {
throw serde::unimplemented_error("serde_adaptor<reflect_from_name>::into(reflect_from_name, key, data)");
}
};


template<typename M, class T>
constexpr M& mem_get(T& type, std::string_view member_name) {
auto ref = serde::reflect_from_name<M>(member_name);
serde::deserialize_to(ref, type);
if(ref.member == nullptr) {
throw serde::type_error("can't find member: " + std::string(member_name));
}
return *ref.member;
}

template<typename M, size_t idx, class T>
constexpr M& mem_get(T& type) {
auto ref = serde::reflect_from_index<M,idx>();
serde::deserialize_to(ref, type);
if(ref.member == nullptr) {
throw serde::type_error("out of index: " + std::to_string(idx));
}
return *ref.member;
}
}

#endif
9 changes: 9 additions & 0 deletions include/serdepp/exception.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,15 @@ namespace serde {
std::string what_;
};

struct type_error : exception {
public:
explicit type_error(std::string what) : what_("type error: " + what + '\n') {}
virtual ~type_error() noexcept override = default;
virtual const char* what() const noexcept override {return what_.c_str();}
protected:
std::string what_;
};

struct unregisted_data_error : exception {
public:
explicit unregisted_data_error(std::string what) : what_("unregisted data: " + what + '\n') {}
Expand Down
1 change: 1 addition & 0 deletions include/serdepp/serde.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@
#include <serdepp/utility.hpp>
#include <serdepp/adaptor/sstream.hpp>
#include <serdepp/ostream.hpp>
using namespace serde::ostream;

#endif
21 changes: 11 additions & 10 deletions include/serdepp/serializer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -513,14 +513,14 @@ namespace serde

template<typename Format, typename=void>
struct serde_type_checker {
static bool is_integer(Format& format);
static bool is_sequence(Format& format);
static bool is_map(Format& format);
static bool is_float(Format& format);
static bool is_string(Format& format);
static bool is_bool(Format& format);
static bool is_null(Format& format);
static bool is_struct(Format& format);
static bool is_integer(Format& format) { return true; }
static bool is_sequence(Format& format) { return true; }
static bool is_map(Format& format) { return true; }
static bool is_float(Format& format) { return true; }
static bool is_string(Format& format) { return true; }
static bool is_bool(Format& format) { return true; }
static bool is_null(Format& format) { return true; }
static bool is_struct(Format& format) { return true; }
};

template<class T>
Expand Down Expand Up @@ -574,15 +574,16 @@ namespace serde
data = deserialize<T>(format);
return false;
} catch(std::exception& ex) {
std::cout << "error \n";
return true;
}
}

template<class Format, class V, class Cur, class ...T>
constexpr void serde_variant_iter(Format& format, V& data) {
if constexpr (sizeof...(T) != 0) {
bool is_find = serde_variant_setter<Format, Cur, V>(format, data);
if(!is_find) return;
bool is_not_find = serde_variant_setter<Format, Cur, V>(format, data);
if(!is_not_find) return;
serde_variant_iter<Format, V, T...>(format, data);
} else {
if(serde_variant_setter<Format,
Expand Down
2 changes: 2 additions & 0 deletions include/serdepp/utility.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,6 @@
__VA_ARGS__; \
} \

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

#endif

0 comments on commit 1ec0fd1

Please sign in to comment.