Skip to content
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

[struct_pb][feat]to proto #702

Merged
merged 3 commits into from
Jul 2, 2024
Merged
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
7 changes: 7 additions & 0 deletions include/ylt/standalone/iguana/detail/pb_type.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#pragma once
#include <type_traits>

namespace iguana {

Expand Down Expand Up @@ -87,6 +88,12 @@ inline bool operator<(const sfixed64_t& lhs, const sfixed64_t& rhs) {
return lhs.val < rhs.val;
}

template <typename Type, typename T = std::decay_t<Type>>
constexpr bool is_pb_type_v =
std::is_same_v<sint32_t, T> || std::is_same_v<sint64_t, T> ||
std::is_same_v<fixed32_t, T> || std::is_same_v<fixed64_t, T> ||
std::is_same_v<sfixed32_t, T> || std::is_same_v<sfixed64_t, T>;

} // namespace iguana

// for key in std::unordered_map
Expand Down
171 changes: 171 additions & 0 deletions include/ylt/standalone/iguana/dynamic.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
#pragma once
#include "reflection.hpp"

namespace iguana {
using base = detail::base;

template <typename T, typename U>
IGUANA_INLINE constexpr size_t member_offset(T* t, U T::*member) {
return (char*)&(t->*member) - (char*)t;
}

constexpr inline uint8_t ENABLE_JSON = 0x01;
constexpr inline uint8_t ENABLE_YAML = 0x02;
constexpr inline uint8_t ENABLE_XML = 0x04;
constexpr inline uint8_t ENABLE_PB = 0x08;
constexpr inline uint8_t ENABLE_ALL = 0x0F;

template <typename T, uint8_t ENABLE_FLAG = ENABLE_PB>
struct base_impl : public base {
void to_pb(std::string& str) override {
if constexpr ((ENABLE_FLAG & ENABLE_PB) != 0) {
to_pb_adl((iguana_adl_t*)nullptr, *(static_cast<T*>(this)), str);
}
else {
throw std::runtime_error("Protobuf Disabled");
}
}

void from_pb(std::string_view str) override {
if constexpr ((ENABLE_FLAG & ENABLE_PB) != 0) {
from_pb_adl((iguana_adl_t*)nullptr, *(static_cast<T*>(this)), str);
}
else {
throw std::runtime_error("Protobuf Disabled");
}
}

void to_json(std::string& str) override {
if constexpr ((ENABLE_FLAG & ENABLE_JSON) != 0) {
to_json_adl((iguana_adl_t*)nullptr, *(static_cast<T*>(this)), str);
}
else {
throw std::runtime_error("Json Disabled");
}
}

void from_json(std::string_view str) override {
if constexpr ((ENABLE_FLAG & ENABLE_JSON) != 0) {
from_json_adl((iguana_adl_t*)nullptr, *(static_cast<T*>(this)), str);
}
else {
throw std::runtime_error("Json Disabled");
}
}

void to_xml(std::string& str) override {
if constexpr ((ENABLE_FLAG & ENABLE_XML) != 0) {
to_xml_adl((iguana_adl_t*)nullptr, *(static_cast<T*>(this)), str);
}
else {
throw std::runtime_error("Xml Disabled");
}
}

void from_xml(std::string_view str) override {
if constexpr ((ENABLE_FLAG & ENABLE_XML) != 0) {
from_xml_adl((iguana_adl_t*)nullptr, *(static_cast<T*>(this)), str);
}
else {
throw std::runtime_error("Xml Disabled");
}
}

void to_yaml(std::string& str) override {
if constexpr ((ENABLE_FLAG & ENABLE_YAML) != 0) {
to_yaml_adl((iguana_adl_t*)nullptr, *(static_cast<T*>(this)), str);
}
else {
throw std::runtime_error("Yaml Disabled");
}
}

void from_yaml(std::string_view str) override {
if constexpr ((ENABLE_FLAG & ENABLE_YAML) != 0) {
from_yaml_adl((iguana_adl_t*)nullptr, *(static_cast<T*>(this)), str);
}
else {
throw std::runtime_error("Yaml Disabled");
}
}

iguana::detail::field_info get_field_info(std::string_view name) override {
static constexpr auto map = iguana::get_members<T>();
iguana::detail::field_info info{};
for (auto& [no, field] : map) {
if (info.offset > 0) {
break;
}
std::visit(
[&](auto val) {
if (val.field_name == name) {
info.offset = member_offset((T*)this, val.member_ptr);
using value_type = typename decltype(val)::value_type;
#if defined(__clang__) || defined(_MSC_VER) || \
(defined(__GNUC__) && __GNUC__ > 8)
info.type_name = type_string<value_type>();
#endif
}
},
field);
}

return info;
}

std::vector<std::string_view> get_fields_name() const override {
static constexpr auto map = iguana::get_members<T>();

std::vector<std::string_view> vec;

for (auto const& [no, val] : map) {
std::visit(
[&](auto const& field) {
std::string_view const current_name{field.field_name.data(),
field.field_name.size()};
if (vec.empty() || (vec.back() != current_name)) {
vec.push_back(current_name);
}
},
val);
}
return vec;
}

std::any get_field_any(std::string_view name) const override {
static constexpr auto map = iguana::get_members<T>();
std::any result;

for (auto [no, field] : map) {
if (result.has_value()) {
break;
}
std::visit(
[&](auto val) {
if (val.field_name == name) {
using value_type = typename decltype(val)::value_type;
auto const offset = member_offset((T*)this, val.member_ptr);
auto ptr = (((char*)this) + offset);
result = {*((value_type*)ptr)};
}
},
field);
}

return result;
}

virtual ~base_impl() {}

size_t cache_size = 0;
};

IGUANA_INLINE std::shared_ptr<base> create_instance(std::string_view name) {
auto it = iguana::detail::g_pb_map.find(name);
if (it == iguana::detail::g_pb_map.end()) {
throw std::invalid_argument(std::string(name) +
"not inheried from iguana::base_impl");
}
return it->second();
}
} // namespace iguana
10 changes: 10 additions & 0 deletions include/ylt/standalone/iguana/iguana.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#pragma once
#include "iguana/dynamic.hpp"
#include "iguana/json_reader.hpp"
#include "iguana/json_writer.hpp"
#include "iguana/pb_reader.hpp"
#include "iguana/pb_writer.hpp"
#include "iguana/xml_reader.hpp"
#include "iguana/xml_writer.hpp"
#include "iguana/yaml_reader.hpp"
#include "iguana/yaml_writer.hpp"
11 changes: 11 additions & 0 deletions include/ylt/standalone/iguana/json_reader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,11 @@ IGUANA_INLINE void from_json_impl(U &value, It &&it, It &&end) {
}
}

template <typename U, typename It, std::enable_if_t<is_pb_type_v<U>, int> = 0>
IGUANA_INLINE void from_json_impl(U &value, It &&it, It &&end) {
from_json_impl(value.val, it, end);
}

template <typename U, typename It, std::enable_if_t<numeric_str_v<U>, int> = 0>
IGUANA_INLINE void from_json_impl(U &value, It &&it, It &&end) {
skip_ws(it, end);
Expand Down Expand Up @@ -899,4 +904,10 @@ IGUANA_INLINE void from_json_file(T &value, const std::string &filename,
}
}

template <typename T>
IGUANA_INLINE void from_json_adl(iguana_adl_t *p, T &t,
std::string_view pb_str) {
iguana::from_json(t, pb_str);
}

} // namespace iguana
1 change: 1 addition & 0 deletions include/ylt/standalone/iguana/json_util.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#pragma once

#include "detail/pb_type.hpp"
#include "util.hpp"
#include "value.hpp"

Expand Down
23 changes: 20 additions & 3 deletions include/ylt/standalone/iguana/json_writer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ template <bool Is_writing_escape = true, typename Stream, typename T,
IGUANA_INLINE void to_json(T &&t, Stream &s);
namespace detail {
template <bool Is_writing_escape = true, typename Stream, typename T>
IGUANA_INLINE void to_json_impl(Stream &ss, std::optional<T> &val);
IGUANA_INLINE void to_json_impl(Stream &ss, const std::optional<T> &val);

template <bool Is_writing_escape = true, typename Stream, typename T,
std::enable_if_t<fixed_array_v<T>, int> = 0>
Expand Down Expand Up @@ -76,6 +76,12 @@ IGUANA_INLINE void to_json_impl(Stream &ss, T value) {
ss.append(temp, p - temp);
}

template <bool Is_writing_escape, typename Stream, typename T,
std::enable_if_t<is_pb_type_v<T>, int> = 0>
IGUANA_INLINE void to_json_impl(Stream &ss, T value) {
to_json_impl<Is_writing_escape>(ss, value.val);
}

template <bool Is_writing_escape, typename Stream, typename T,
std::enable_if_t<numeric_str_v<T>, int> = 0>
IGUANA_INLINE void to_json_impl(Stream &ss, T v) {
Expand All @@ -97,12 +103,18 @@ IGUANA_INLINE void to_json_impl(Stream &ss, T &&t) {

template <bool Is_writing_escape, typename Stream, typename T,
std::enable_if_t<num_v<T>, int> = 0>
IGUANA_INLINE void render_key(Stream &ss, T &t) {
IGUANA_INLINE void render_key(Stream &ss, const T &t) {
ss.push_back('"');
to_json_impl<Is_writing_escape>(ss, t);
ss.push_back('"');
}

template <bool Is_writing_escape, typename Stream, typename T,
std::enable_if_t<is_pb_type_v<T>, int> = 0>
IGUANA_INLINE void render_key(Stream &ss, const T &t) {
render_key<Is_writing_escape>(ss, t.val);
}

template <bool Is_writing_escape, typename Stream, typename T,
std::enable_if_t<string_container_v<T>, int> = 0>
IGUANA_INLINE void render_key(Stream &ss, T &&t) {
Expand Down Expand Up @@ -140,7 +152,7 @@ IGUANA_INLINE void to_json_impl(Stream &ss, T val) {
}

template <bool Is_writing_escape, typename Stream, typename T>
IGUANA_INLINE void to_json_impl(Stream &ss, std::optional<T> &val) {
IGUANA_INLINE void to_json_impl(Stream &ss, const std::optional<T> &val) {
if (!val) {
ss.append("null");
}
Expand Down Expand Up @@ -282,5 +294,10 @@ IGUANA_INLINE void to_json(T &&t, Stream &s) {
to_json_impl<Is_writing_escape>(s, t);
}

template <typename T>
IGUANA_INLINE void to_json_adl(iguana_adl_t *p, T &t, std::string &pb_str) {
to_json(t, pb_str);
}

} // namespace iguana
#endif // SERIALIZE_JSON_HPP
8 changes: 7 additions & 1 deletion include/ylt/standalone/iguana/pb_reader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
#include "pb_util.hpp"

namespace iguana {

template <typename T>
IGUANA_INLINE void from_pb(T& t, std::string_view pb_str);
namespace detail {

template <typename T>
Expand Down Expand Up @@ -254,4 +255,9 @@ IGUANA_INLINE void from_pb(T& t, std::string_view pb_str) {
}
}
}

template <typename T>
IGUANA_INLINE void from_pb_adl(iguana_adl_t* p, T& t, std::string_view pb_str) {
iguana::from_pb(t, pb_str);
}
} // namespace iguana
Loading
Loading