3#include "ll/api/reflection/Reflection.h"
4#include "ll/api/reflection/SerializationError.h"
14namespace ll::reflection {
16template <
class J,
class T>
17inline Expected<J> serialize_impl(T&& vec, meta::PriorityTag<5>)
18 requires(concepts::IsVectorBase<std::remove_cvref_t<T>>);
19template <
class J,
class T>
20inline Expected<J> serialize_impl(T&& d, meta::PriorityTag<5>)
21 requires(concepts::IsDispatcher<std::remove_cvref_t<T>>);
22template <
class J,
class T>
23inline Expected<J> serialize_impl(T&& opt, meta::PriorityTag<5>)
24 requires(concepts::IsOptional<std::remove_cvref_t<T>>);
25template <
class J,
class T>
26inline Expected<J> serialize_impl(T&& str, meta::PriorityTag<4>)
27 requires(concepts::IsString<std::remove_cvref_t<T>>);
28template <
class J,
class T>
29inline Expected<J> serialize_impl(T&& tuple, meta::PriorityTag<3>)
30 requires(concepts::TupleLike<std::remove_cvref_t<T>>);
31template <
class J,
class T>
32inline Expected<J> serialize_impl(T&& arr, meta::PriorityTag<2>)
33 requires(concepts::ArrayLike<std::remove_cvref_t<T>>);
34template <
class J,
class T>
35inline Expected<J> serialize_impl(T&& map, meta::PriorityTag<2>)
36 requires(concepts::Associative<std::remove_cvref_t<T>>);
37template <
class J,
class T>
38inline Expected<J> serialize_impl(T&& obj, meta::PriorityTag<1>)
39 requires(Reflectable<std::remove_cvref_t<T>>);
40template <
class J,
class T>
41inline Expected<J> serialize_impl(T&& e, meta::PriorityTag<1>)
42 requires(std::is_enum_v<std::remove_cvref_t<T>>);
43template <
class J,
class T>
44inline Expected<J> serialize_impl(T&& obj, meta::PriorityTag<0>)
45 requires(std::convertible_to<std::remove_cvref_t<T>, J>);
47template <
class J,
class T>
48[[nodiscard]]
inline Expected<J>
serialize(T&& t)
noexcept
49#if !defined(__INTELLISENSE__)
50 requires(
requires(T&& t) { serialize_impl<J>(std::forward<T>(t), meta::PriorityTag<5>{}); })
53 return serialize_impl<J>(std::forward<T>(t), meta::PriorityTag<5>{});
55 return makeExceptionError();
58template <
class J,
class T>
59[[nodiscard]]
inline Expected<> serialize_to(J& j, T&& t)
noexcept {
63 return forwardError(res.error());
68template <
class J,
class T>
69inline Expected<J> serialize_impl(T&& vec, meta::PriorityTag<5>)
70 requires(concepts::IsVectorBase<std::remove_cvref_t<T>>)
72 Expected<J> res{J::array()};
73 std::remove_cvref_t<T>::forEachComponent([&]<
typename axis_type,
size_t iter> {
75 if (
auto v =
serialize<J>(std::forward<T>(vec).
template get<axis_type, iter>()); v) {
76 res->push_back(*std::move(v));
78 res = makeSerIndexError(iter, v.error());
84template <
class J,
class T>
85inline Expected<J> serialize_impl(T&& d, meta::PriorityTag<5>)
86 requires(concepts::IsDispatcher<std::remove_cvref_t<T>>)
90template <
class J,
class T>
91inline Expected<J> serialize_impl(T&& opt, meta::PriorityTag<5>)
92 requires(concepts::IsOptional<std::remove_cvref_t<T>>)
99template <
class J,
class T>
100inline Expected<J> serialize_impl(T&& str, meta::PriorityTag<4>)
101 requires(concepts::IsString<std::remove_cvref_t<T>>)
103 return std::string{std::forward<T>(str)};
105template <
class J,
class T>
106inline Expected<J> serialize_impl(T&& tuple, meta::PriorityTag<3>)
107 requires(concepts::TupleLike<std::remove_cvref_t<T>>)
109 Expected<J> res{J::array()};
111 [&](
auto&&... args) {
115 if (
auto v =
serialize<J>(std::forward<
decltype((arg))>(arg)); v) {
116 res->push_back(*std::move(v));
119 res = makeSerIndexError(iter, v.error());
122 }(std::forward<decltype((args))>(args))),
125 std::forward<decltype((tuple))>(tuple)
129template <
class J,
class T>
130inline Expected<J> serialize_impl(T&& arr, meta::PriorityTag<2>)
131 requires(concepts::ArrayLike<std::remove_cvref_t<T>>)
133 Expected<J> res{J::array()};
135 for (
auto&& val : std::forward<T>(arr)) {
136 if (
auto v =
serialize<J>(std::forward<
decltype((val))>(val)); v) {
137 res->push_back(*std::move(v));
140 res = makeSerIndexError(iter, v.error());
146template <
class J,
class T>
147inline Expected<J> serialize_impl(T&& map, meta::PriorityTag<2>)
148 requires(concepts::Associative<std::remove_cvref_t<T>>)
150 using RT = std::remove_cvref_t<T>;
152 (concepts::IsString<typename RT::key_type> || std::is_enum_v<typename RT::key_type>),
153 "the key type of the associative container must be convertible to a string"
155 Expected<J> res{J::object()};
156 for (
auto&& [k, v] : map) {
158 if constexpr (std::is_enum_v<typename RT::key_type>) {
159 key = magic_enum::enum_name(std::forward<
decltype((k))>(k));
161 key = std::string{std::forward<decltype((k))>(k)};
163 if (
auto sv =
serialize<J>(std::forward<
decltype((v))>(v)); sv) {
164 (*res)[key] = *std::move(sv);
166 res = makeSerKeyError(key, sv.error());
172template <
class J,
class T>
173inline Expected<J> serialize_impl(T&& obj, meta::PriorityTag<1>)
174 requires(Reflectable<std::remove_cvref_t<T>>)
176 Expected<J> res{J::object()};
177 forEachMember(obj, [&](std::string_view name,
auto&& member) {
178 if (name.starts_with(
'$') || !res) {
181 using member_type =
decltype((member));
182 if constexpr (
requires(member_type m) {
serialize<J>(m); }) {
183 auto v =
serialize<J>(std::forward<member_type>(member));
185 if (!v->is_null()) (*res)[std::string{name}] = *std::move(v);
187 res = makeSerMemberError(std::string{name}, v.error());
190 static_assert(traits::always_false<member_type>,
"this type can't serialize");
195template <
class J,
class T>
196inline Expected<J> serialize_impl(T&& e, meta::PriorityTag<1>)
197 requires(std::is_enum_v<std::remove_cvref_t<T>>)
199 return magic_enum::enum_name(std::forward<T>(e));
201template <
class J,
class T>
202inline Expected<J> serialize_impl(T&& obj, meta::PriorityTag<0>)
203 requires(std::convertible_to<std::remove_cvref_t<T>, J>)
205 return std::forward<T>(obj);
Definition serialize.h:11