2#include "ll/api/base/FixedString.h"
3#include "ll/api/base/TypeTraits.h"
4#include <ll/api/reflection/Reflection.h>
5#include <ll/api/reflection/ReflectionError.h>
6#include <ll/api/reflection/Serializer.h>
23namespace ll::reflection {
27template <
typename J,
typename T, IsKeyFormatter F>
28inline Expected<J> serialize_impl(T&& t, F
const& keyFormatter, meta::PriorityTag<11>)
29 requires(std::is_arithmetic_v<std::remove_cvref_t<T>>);
30template <
typename J,
typename T, IsKeyFormatter F>
31inline Expected<J> serialize_impl(T&& t, F
const& keyFormatter, meta::PriorityTag<10>)
32 requires(detail::has_custom_serializer_v<std::remove_cvref_t<T>, J, F>);
33template <
typename J,
typename T, IsKeyFormatter F>
34inline Expected<J> serialize_impl(T&& t, F
const& keyFormatter, meta::PriorityTag<9>)
35 requires(concepts::IsOptional<std::remove_cvref_t<T>>);
36template <
typename J,
typename T, IsKeyFormatter F>
37inline Expected<J> serialize_impl(T&& t, F
const& keyFormatter, meta::PriorityTag<9>)
38 requires(concepts::IsDispatcher<std::remove_cvref_t<T>>);
39template <
typename J,
typename T, IsKeyFormatter F>
40inline Expected<J> serialize_impl(T&& t, F
const& keyFormatter, meta::PriorityTag<8>)
41 requires(concepts::IsVectorBase<std::remove_cvref_t<T>>);
42template <
class J,
typename T, IsKeyFormatter F>
43inline Expected<J> serialize_impl(T&& t, F
const& keyFormatter, meta::PriorityTag<7>)
44 requires(std::is_enum_v<std::remove_cvref_t<T>>);
45template <
class J,
typename T, IsKeyFormatter F>
46inline Expected<J> serialize_impl(T&& t, F
const& keyFormatter, meta::PriorityTag<6>)
47 requires(concepts::IsVariant<std::remove_cvref_t<T>>);
48template <
class J,
typename T, IsKeyFormatter F>
49inline Expected<J> serialize_impl(T&& t, F
const& keyFormatter, meta::PriorityTag<5>)
50 requires(concepts::IsStringConvertible<std::remove_cvref_t<T>>);
51template <
class J,
typename T, IsKeyFormatter F>
52inline Expected<J> serialize_impl(T&& t, F
const& keyFormatter, meta::PriorityTag<4>)
53 requires(concepts::TupleLike<std::remove_cvref_t<T>>);
54template <
typename J,
typename T, IsKeyFormatter F>
55inline Expected<J> serialize_impl(T&& t, F
const& keyFormatter, meta::PriorityTag<3>)
56 requires(concepts::ArrayLike<std::remove_cvref_t<T>>);
57template <
typename J,
typename T, IsKeyFormatter F>
58inline Expected<J> serialize_impl(T&& t, F
const& keyFormatter, meta::PriorityTag<2>)
59 requires(concepts::Associative<std::remove_cvref_t<T>>);
60template <
typename J,
typename T, IsKeyFormatter F>
61inline Expected<J> serialize_impl(T&& t, F
const& keyFormatter, meta::PriorityTag<1>)
63template <
typename J,
typename T, IsKeyFormatter F>
64inline Expected<J> serialize_impl(T&& t, F
const& keyFormatter, meta::PriorityTag<0>);
68template <
typename J,
typename T, IsKeyFormatter F>
69inline Expected<J> serialize(T&& t, F
const& keyFormatter)
noexcept
70#if !defined(__INTELLISENSE__)
71 requires(
requires(T&& t, F
const& keyFormatter) {
72 serialize_impl<J>(std::forward<T>(t), keyFormatter, meta::PriorityTag<11>{});
76 return serialize_impl<J>(std::forward<T>(t), keyFormatter, meta::PriorityTag<11>{});
78 return makeExceptionError();
81template <
typename J,
typename T>
82inline Expected<J> serialize(T&& t)
noexcept {
83 return serialize<J>(std::forward<T>(t), detail::default_key_formatter);
86template <
class J,
class T, IsKeyFormatter F>
87inline Expected<> serialize_to(J& j, T&& t, F
const& keyFormatter)
noexcept {
88 if (
auto res = serialize<J>(std::forward<T>(t), keyFormatter); res) {
91 return forwardError(res.error());
96template <
class J,
class T>
97inline Expected<> serialize_to(J& j, T&& t)
noexcept {
98 return serialize_to<J>(j, std::forward<T>(t), detail::default_key_formatter);
101template <auto MemberPtr,
class J,
class T, IsKeyFormatter F>
102inline Expected<> member_serialize(J& j, T&& t, F
const& keyFormatter)
noexcept
103 requires(!std::is_const_v<std::remove_reference_t<J>>)
105 static_assert(!typeNameStem(getRawName<MemberPtr>()).empty(),
"member name is empty");
106 if (!j.is_object())
return makeSerObjectTypeError();
107 auto result = serialize<J>(t.*MemberPtr, keyFormatter);
108 if (!result)
return ll::forwardError(result.error());
109 j[keyFormatter(typeNameStem(getRawName<MemberPtr>()))] = *std::move(result);
113template <ll::FixedString Key,
class J,
class T, IsKeyFormatter F>
114inline Expected<> field_serialize(J& j, T&& t, F
const& keyFormatter)
noexcept
115 requires(!std::is_const_v<std::remove_reference_t<J>>)
117 static_assert(Key.size() != 0,
"field name is empty");
118 if (!j.is_object())
return makeSerObjectTypeError();
120 auto key = keyFormatter(Key.sv());
122 if constexpr (concepts::IsOptional<std::remove_cvref_t<T>>) {
123 if (!t.has_value()) {
126 auto result = serialize<J>(*t, keyFormatter);
127 if (!result)
return ll::forwardError(result.error());
128 j[key] = *std::move(result);
130 auto result = serialize<J>(std::forward<T>(t), keyFormatter);
131 if (!result)
return ll::forwardError(result.error());
132 j[key] = *std::move(result);
138template <auto MemberPtr,
class J,
class T>
139inline Expected<> member_serialize(J& j, T&& t)
noexcept
140 requires(!std::is_const_v<std::remove_reference_t<J>>)
142 return member_serialize<MemberPtr>(j, std::forward<T>(t), detail::default_key_formatter);
145template <ll::FixedString Key,
class J,
class T>
146inline Expected<> field_serialize(J& j, T&& t)
noexcept
147 requires(!std::is_const_v<std::remove_reference_t<J>>)
149 return field_serialize<Key>(j, std::forward<T>(t), detail::default_key_formatter);
152template <auto MemberPtr,
class T,
class J, IsKeyFormatter F>
153inline Expected<> member(T&& t, J& j, F
const& keyFormatter)
noexcept
154 requires(!std::is_const_v<std::remove_reference_t<J>>)
156 return member_serialize<MemberPtr>(j, std::forward<T>(t), keyFormatter);
159template <ll::FixedString Key,
class T,
class J, IsKeyFormatter F>
160inline Expected<> field(T&& t, J& j, F
const& keyFormatter)
noexcept
161 requires(!std::is_const_v<std::remove_reference_t<J>>)
163 return field_serialize<Key>(j, std::forward<T>(t), keyFormatter);
166template <auto MemberPtr,
class T,
class J>
167inline Expected<> member(T&& t, J& j)
noexcept
168 requires(!std::is_const_v<std::remove_reference_t<J>>)
170 return member<MemberPtr>(std::forward<T>(t), j, detail::default_key_formatter);
173template <ll::FixedString Key,
class T,
class J>
174inline Expected<> field(T&& t, J& j)
noexcept
175 requires(!std::is_const_v<std::remove_reference_t<J>>)
177 return field<Key>(std::forward<T>(t), j, detail::default_key_formatter);
182template <
typename J,
typename T, IsKeyFormatter F>
183inline Expected<J> serialize_impl(T&& t, F
const&, meta::PriorityTag<11>)
184 requires(std::is_arithmetic_v<std::remove_cvref_t<T>>)
189template <
typename J,
typename T, IsKeyFormatter F>
190inline Expected<J> serialize_impl(T&& t, F
const& keyFormatter, meta::PriorityTag<10>)
191 requires(detail::has_custom_serializer_v<std::remove_cvref_t<T>, J, F>)
193 using RT = std::remove_cvref_t<T>;
194 if constexpr (detail::has_value_serializer_v<RT, J, F>) {
195 using JT = std::remove_cvref_t<J>;
196 auto result = [&]() ->
decltype(
auto) {
201 }
else if constexpr (
requires {
209 using Result = std::remove_cvref_t<
decltype(result)>;
210 if constexpr (concepts::IsLeviExpected<Result>) {
212 return forwardError(result.error());
214 if constexpr (std::same_as<std::remove_cvref_t<
decltype(*result)>, J>) {
215 return *std::move(result);
217 return J(*std::move(result));
220 if constexpr (std::same_as<Result, J>) {
221 return std::move(result);
223 return J(std::move(result));
230 return forwardError(res.error());
234 return forwardError(res.error());
241template <
typename J,
typename T, IsKeyFormatter F>
242inline Expected<J> serialize_impl(T&& t, F
const& keyFormatter, meta::PriorityTag<9>)
243 requires(concepts::IsOptional<std::remove_cvref_t<T>>)
245 return t ? serialize_impl<J>(*std::forward<T>(t), keyFormatter, meta::PriorityTag<11>{}) : nullptr;
248template <
typename J,
typename T, IsKeyFormatter F>
249inline Expected<J> serialize_impl(T&& t, F
const& keyFormatter, meta::PriorityTag<9>)
250 requires(concepts::IsDispatcher<std::remove_cvref_t<T>>)
252 return serialize_impl<J>(std::forward<T>(t).storage, keyFormatter, meta::PriorityTag<11>{});
255template <
typename J,
typename T, IsKeyFormatter F>
256inline Expected<J> serialize_impl(T&& t, F
const& keyFormatter, meta::PriorityTag<8>)
257 requires(concepts::IsVectorBase<std::remove_cvref_t<T>>)
259 Expected<J> res{J::array()};
260 std::remove_cvref_t<T>::forEachComponent([&]<
typename axis_type,
size_t iter> {
262 if (
auto v = serialize<J>(std::forward<T>(t).
template get<axis_type, iter>(), keyFormatter); v) {
263 res->push_back(*std::move(v));
265 res = makeSerIndexError(iter, v.error());
272template <
class J,
typename T, IsKeyFormatter F>
273inline Expected<J> serialize_impl(T&& t, F
const& keyFormatter, meta::PriorityTag<7>)
274 requires(std::is_enum_v<std::remove_cvref_t<T>>)
276 using enum_type = std::remove_cvref_t<T>;
277 if (
auto name = detail::enum_name_to_string<enum_type>(t, keyFormatter)) {
278 return *std::move(name);
280 return fmt::underlying(t);
283template <
class J,
typename T, IsKeyFormatter F>
284inline Expected<J> serialize_impl(T&& t, F
const& keyFormatter, meta::PriorityTag<6>)
285 requires(concepts::IsVariant<std::remove_cvref_t<T>>)
288 [&](
auto const& value) {
return serialize_impl<J>(value, keyFormatter, meta::PriorityTag<11>{}); },
293template <
class J,
typename T, IsKeyFormatter F>
294inline Expected<J> serialize_impl(T&& t, F
const&, meta::PriorityTag<5>)
295 requires(concepts::IsStringConvertible<std::remove_cvref_t<T>>)
297 return J(std::string{std::forward<T>(t)});
300template <
class J,
typename T, IsKeyFormatter F>
301inline Expected<J> serialize_impl(T&& t, F
const& keyFormatter, meta::PriorityTag<4>)
302 requires(concepts::TupleLike<std::remove_cvref_t<T>>)
304 Expected<J> res{J::array()};
306 [&](
auto&&... args) {
311 serialize_impl<J>(std::forward<
decltype(arg)>(arg), keyFormatter, meta::PriorityTag<11>{});
313 res->push_back(*std::move(v));
316 res = makeSerIndexError(iter, v.error());
319 }(std::forward<decltype(args)>(args))),
322 std::forward<decltype(t)>(t)
327template <
typename J,
typename T, IsKeyFormatter F>
328inline Expected<J> serialize_impl(T&& t, F
const& keyFormatter, meta::PriorityTag<3>)
329 requires(concepts::ArrayLike<std::remove_cvref_t<T>>)
331 Expected<J> res{J::array()};
333 for (
auto&& val : std::forward<T>(t)) {
334 if (
auto v = serialize_impl<J>(std::forward<
decltype(val)>(val), keyFormatter, meta::PriorityTag<11>{}); v) {
335 res->push_back(*std::move(v));
338 res = makeSerIndexError(iter, v.error());
345template <
typename J,
typename T, IsKeyFormatter F>
346inline Expected<J> serialize_impl(T&& t, F
const& keyFormatter, meta::PriorityTag<2>)
347 requires(concepts::Associative<std::remove_cvref_t<T>>)
350 detail::is_key_stringifiable_v<typename std::remove_cvref_t<T>::key_type>,
351 "an associative container key has to be a string, an enum, or a type with a "
352 "ll::reflection::Serializer<T>::to_string / from_string specialization"
354 Expected<J> res{J::object()};
355 for (
auto&& [k, v] : t) {
356 auto key = type_to_string(k, keyFormatter);
357 if (
auto sv = serialize_impl<J>(std::forward<
decltype(v)>(v), keyFormatter, meta::PriorityTag<11>{}); sv) {
358 (*res)[key] = *std::move(sv);
360 res = makeSerKeyError(key, sv.error());
367template <
typename J,
typename T, IsKeyFormatter F>
368inline Expected<J> serialize_impl(T&& t, F
const& keyFormatter, meta::PriorityTag<1>)
371 Expected<J> res{J::object()};
372 forEachMember(t, [&](std::string_view name,
auto&& member) {
374 auto key = keyFormatter(name);
375 auto v = serialize_impl<J>(std::forward<
decltype((member))>(member), keyFormatter, meta::PriorityTag<11>{});
377 if (!v->is_null()) (*res)[key] = *std::move(v);
379 res = makeSerMemberError(key, v.error());
385template <
typename J,
typename T, IsKeyFormatter F>
386inline Expected<J> serialize_impl(T&&, F
const&, meta::PriorityTag<0>) {
388 traits::always_false<std::remove_cvref_t<T>>,
389 "cannot serialize this type: provide a ll::reflection::Serializer<T> specialization, or use an "
390 "arithmetic type, a string, an optional, a dispatcher, an enum, a variant, a tuple-like, an array-like "
391 "or associative container, or a reflectable aggregate"
Definition Reflection.h:33
Definition Serializer.h:9