Skip to content
LeviMC
English
AutoLightDark
LeviLamina
Loading...
Searching...
No Matches
Deserialization.h
1#pragma once
2#include "fmt/format.h"
3#include "ll/api/base/FixedString.h"
4#include "ll/api/reflection/Reflection.h"
5#include "ll/api/reflection/ReflectionError.h"
6#include "ll/api/reflection/Serializer.h"
7#include "mc/deps/nbt/CompoundTagVariant.h"
8#include <cmath>
9#include <limits>
10#include <memory>
11
12// Priority:
13// 11. Arithmetic
14// 10. Custom Specialization
15// 9. Optional / Dispatcher
16// 8. IsVectorBase
17// 7. Enum
18// 6. Variant
19// 5. String
20// 4. TupleLike
21// 3. ArrayLike
22// 2. Associative
23// 1. Reflectable
24// 0. Convertible
25
26namespace ll::reflection {
27
28namespace {
29
30template <class T, class J, IsKeyFormatter F>
31inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F const& keyFormatter, meta::PriorityTag<11>)
32 requires(std::is_arithmetic_v<std::remove_cvref_t<T>>);
33template <class T, class J, IsKeyFormatter F>
34inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F const& keyFormatter, meta::PriorityTag<10>)
35 requires(
36 detail::has_value_deserializer_v<std::remove_cvref_t<T>, J, F>
37 || detail::is_string_serializable_v<std::remove_cvref_t<T>>
38 );
39template <class T, class J, IsKeyFormatter F>
40inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F const& keyFormatter, meta::PriorityTag<9>)
41 requires(concepts::IsOptional<std::remove_cvref_t<T>>);
42template <class T, class J, IsKeyFormatter F>
43inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F const& keyFormatter, meta::PriorityTag<9>)
44 requires(concepts::IsDispatcher<std::remove_cvref_t<T>>);
45template <class T, class J, IsKeyFormatter F>
46inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F const& keyFormatter, meta::PriorityTag<8>)
47 requires(concepts::IsVectorBase<std::remove_cvref_t<T>>);
48template <class T, class J, IsKeyFormatter F>
49inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F const& keyFormatter, meta::PriorityTag<7>)
50 requires(std::is_enum_v<std::remove_cvref_t<T>>);
51template <class T, class J, IsKeyFormatter F>
52inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F const& keyFormatter, meta::PriorityTag<6>)
53 requires(concepts::IsVariant<std::remove_cvref_t<T>>);
54template <class T, class J, IsKeyFormatter F>
55inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F const& keyFormatter, meta::PriorityTag<5>)
56 requires(
57 concepts::IsString<std::remove_cvref_t<T>> && std::is_assignable_v<std::remove_cvref_t<T>&, std::string>
58 && !std::same_as<std::remove_cvref_t<T>, std::string_view>
59 );
60template <class T, class J, IsKeyFormatter F>
61inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F const& keyFormatter, meta::PriorityTag<5>)
62 requires(std::same_as<std::remove_cvref_t<T>, std::string_view>);
63template <class T, class J, IsKeyFormatter F>
64inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F const& keyFormatter, meta::PriorityTag<4>)
65 requires(concepts::TupleLike<std::remove_cvref_t<T>>);
66template <class T, class J, IsKeyFormatter F>
67inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F const& keyFormatter, meta::PriorityTag<3>)
68 requires(concepts::ArrayLike<std::remove_cvref_t<T>>);
69template <class T, class J, IsKeyFormatter F>
70inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F const& keyFormatter, meta::PriorityTag<2>)
71 requires(concepts::Associative<std::remove_cvref_t<T>>);
72template <class T, class J, IsKeyFormatter F>
73inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F const& keyFormatter, meta::PriorityTag<1>)
75template <class T, class J, IsKeyFormatter F>
76inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F const& keyFormatter, meta::PriorityTag<0>);
77
78template <class T, class J, IsKeyFormatter F>
79inline Expected<> deserialize_inplace_impl(T& t, J&& j, F const& keyFormatter)
80 requires(detail::has_inplace_deserializer_v<std::remove_cvref_t<T>, J, F>);
81
82template <class T, class V>
83inline void replace_deserialized_value(T& target, V&& value);
84
85template <class T, class J, IsKeyFormatter F>
86inline Expected<std::remove_cvref_t<T>> deserialize_construct(J&& j, F const& keyFormatter);
87
88} // namespace
89
90template <class T, class J, IsKeyFormatter F>
91inline Expected<> deserialize(T& t, J&& j, F const& keyFormatter) noexcept try {
92 using RT = std::remove_cvref_t<T>;
93 if constexpr (detail::has_inplace_deserializer_v<RT, J, F>) {
94 return deserialize_inplace_impl(t, std::forward<J>(j), keyFormatter);
95 } else {
96 auto value = deserialize_impl<RT>(std::forward<J>(j), keyFormatter, meta::PriorityTag<11>{});
97 if (!value) return forwardError(value.error());
98 replace_deserialized_value(t, std::move(*value));
99 return {};
100 }
101} catch (...) {
102 return makeExceptionError();
103}
104
105template <class T, class J>
106inline Expected<> deserialize(T& t, J&& j) noexcept {
107 return deserialize<T>(t, std::forward<J>(j), detail::default_key_formatter);
108}
109
110template <class T, class J, IsKeyFormatter F>
111inline Expected<T> deserialize_to(J&& j, F const& keyFormatter) noexcept try {
112 return deserialize_construct<T>(std::forward<J>(j), keyFormatter);
113} catch (...) {
114 return makeExceptionError();
115}
116
117template <class T, class J>
118inline Expected<T> deserialize_to(J&& j) noexcept {
119 return deserialize_to<T>(std::forward<J>(j), detail::default_key_formatter);
120}
121
122namespace {
123
124template <class T, class J, IsKeyFormatter F>
125constexpr bool can_deserialize_construct_from_inplace_v =
126 std::is_default_constructible_v<std::remove_cvref_t<T>>
127 && detail::has_inplace_deserializer_v<std::remove_cvref_t<T>, J, F>;
128
129template <class T, class J, IsKeyFormatter F>
130inline Expected<> deserialize_inplace_impl(T& t, J&& j, F const& keyFormatter)
131 requires(detail::has_inplace_deserializer_v<std::remove_cvref_t<T>, J, F>)
132{
133 using RT = std::remove_cvref_t<T>;
134 using JT = std::remove_cvref_t<J>;
135 if constexpr (requires { Serializer<RT, JT>::deserialize(t, std::forward<J>(j), keyFormatter); }) {
136 return Serializer<RT, JT>::deserialize(t, std::forward<J>(j), keyFormatter);
137 } else if constexpr (requires { Serializer<RT, JT>::deserialize(t, std::forward<J>(j)); }) {
138 return Serializer<RT, JT>::deserialize(t, std::forward<J>(j));
139 } else if constexpr (requires { Serializer<RT>::deserialize(t, std::forward<J>(j), keyFormatter); }) {
140 return Serializer<RT>::deserialize(t, std::forward<J>(j), keyFormatter);
141 } else if constexpr (requires { Serializer<RT>::deserialize(t, std::forward<J>(j)); }) {
142 return Serializer<RT>::deserialize(t, std::forward<J>(j));
143 } else if constexpr (requires { Serializer<RT>::template deserialize<JT>(t, std::forward<J>(j), keyFormatter); }) {
144 return Serializer<RT>::template deserialize<JT>(t, std::forward<J>(j), keyFormatter);
145 } else {
146 return Serializer<RT>::template deserialize<JT>(t, std::forward<J>(j));
147 }
148}
149
150template <class T, class V>
151inline void replace_deserialized_value(T& target, V&& value) {
152 using target_type = std::remove_cvref_t<T>;
153 using value_type = std::remove_cvref_t<V>;
154
155 static_assert(
156 std::same_as<target_type, value_type>,
157 "replace_deserialized_value requires the constructed value to match the target type"
158 );
159
160 if constexpr (std::is_assignable_v<T&, V&&>) {
161 target = std::forward<V>(value);
162 } else {
163 static_assert(!std::is_const_v<target_type>, "deserialize target must not be const");
164 static_assert(!std::is_reference_v<T>, "deserialize target must not be a reference");
165 static_assert(
166 std::is_constructible_v<target_type, V&&>,
167 "deserialize target must be assignable or constructible from the deserialized value"
168 );
169 std::destroy_at(std::addressof(target));
170 std::construct_at(std::addressof(target), std::forward<V>(value));
171 }
172}
173
174template <class T, class J, IsKeyFormatter F>
175inline Expected<std::remove_cvref_t<T>> deserialize_construct(J&& j, F const& keyFormatter) {
176 using RT = std::remove_cvref_t<T>;
177 if constexpr (can_deserialize_construct_from_inplace_v<RT, J, F>) {
178 RT value{};
179 auto res = deserialize(value, std::forward<J>(j), keyFormatter);
180 if (!res) return forwardError(res.error());
181 return value;
182 } else {
183 return deserialize_impl<T>(std::forward<J>(j), keyFormatter, meta::PriorityTag<11>{});
184 }
185}
186
187template <class T, class V>
188inline void array_append_value(T& t, V&& value) {
189 if constexpr (requires(T& a, std::remove_cvref_t<V> v) { a.emplace_back(std::move(v)); }) {
190 t.emplace_back(std::forward<V>(value));
191 } else if constexpr (requires(T& a, std::remove_cvref_t<V> v) { a.push_back(std::move(v)); }) {
192 t.push_back(std::forward<V>(value));
193 } else if constexpr (requires(T& a, std::remove_cvref_t<V> v) { a.insert(a.end(), std::move(v)); }) {
194 t.insert(t.end(), std::forward<V>(value));
195 } else if constexpr (requires(T& a, std::remove_cvref_t<V> v) { a.insert(std::move(v)); }) {
196 t.insert(std::forward<V>(value));
197 } else {
198 static_assert(
199 ll::traits::always_false<std::remove_cvref_t<T>>,
200 "array-like type must support appending a constructed value for deserialization"
201 );
202 }
203}
204
205template <class T, class K, class V>
206inline void associative_insert_value(T& t, K&& key, V&& value) {
207 if constexpr (requires(T& a, std::remove_cvref_t<K> k, std::remove_cvref_t<V> v) {
208 a.try_emplace(std::move(k), std::move(v));
209 }) {
210 t.try_emplace(std::forward<K>(key), std::forward<V>(value));
211 } else if constexpr (requires(T& a, std::remove_cvref_t<K> k, std::remove_cvref_t<V> v) {
212 a.emplace(std::move(k), std::move(v));
213 }) {
214 t.emplace(std::forward<K>(key), std::forward<V>(value));
215 } else if constexpr (requires(T& a, std::remove_cvref_t<K> k, std::remove_cvref_t<V> v) {
216 a.insert_or_assign(std::move(k), std::move(v));
217 }) {
218 t.insert_or_assign(std::forward<K>(key), std::forward<V>(value));
219 } else {
220 static_assert(
221 ll::traits::always_false<std::remove_cvref_t<T>>,
222 "associative type must support inserting a constructed mapped value for deserialization"
223 );
224 }
225}
226
227template <typename Child, typename J>
228[[nodiscard]] inline decltype(auto) array_child_at(J&& j, size_t index) {
229 if constexpr (std::same_as<std::remove_cvref_t<J>, CompoundTagVariant>) {
230 return CompoundTagVariant{j[index]};
231 } else if constexpr (std::same_as<std::remove_cvref_t<J>, UniqueTagPtr>) {
232 return CompoundTagVariant{j[index]};
233 } else if constexpr (std::is_lvalue_reference_v<J&&>) {
234 return static_cast<J&&>(j[index]);
235 } else {
236 return std::remove_cvref_t<J>(j[index]);
237 }
238}
239
240template <typename J, typename K>
241[[nodiscard]] inline decltype(auto) object_child_at(J&& j, K&& key) {
242 if constexpr (std::same_as<std::remove_cvref_t<J>, CompoundTagVariant>) {
243 return CompoundTagVariant{j[std::forward<K>(key)]};
244 } else if constexpr (std::same_as<std::remove_cvref_t<J>, UniqueTagPtr>) {
245 return CompoundTagVariant{j[std::forward<K>(key)]};
246 } else if constexpr (std::is_lvalue_reference_v<J&&>) {
247 return static_cast<J&&>(j[std::forward<K>(key)]);
248 } else {
249 return std::remove_cvref_t<J>(j[std::forward<K>(key)]);
250 }
251}
252
253template <auto MemberPtr, bool AllowOptionalMissing, class T, class J, IsKeyFormatter F>
254inline Expected<> member_deserialize_impl(T& t, J&& j, F const& keyFormatter) {
255 static_assert(!typeNameStem(getRawName<MemberPtr>()).empty(), "member name is empty");
256 if (!j.is_object()) return makeDeserObjectTypeError();
257 auto key = keyFormatter(typeNameStem(getRawName<MemberPtr>()));
258 if (!j.contains(key)) {
259 using MemberT = decltype(t.*MemberPtr);
260 if constexpr (AllowOptionalMissing && concepts::IsOptional<std::remove_cvref_t<MemberT>>) {
261 t.*MemberPtr = std::nullopt;
262 return {};
263 } else {
264 return makeDeserMissingRequiredFieldError(std::string{key});
265 }
266 }
267 decltype(auto) child = object_child_at(std::forward<J>(j), key);
268 return deserialize(t.*MemberPtr, std::forward<decltype(child)>(child), keyFormatter);
269}
270
271template <auto MemberPtr, class T, class D, class J, IsKeyFormatter F>
272inline Expected<> member_deserialize_or_impl(T& t, J&& j, D&& defaultValue, F const& keyFormatter) {
273 static_assert(!typeNameStem(getRawName<MemberPtr>()).empty(), "member name is empty");
274 if (!j.is_object()) return makeDeserObjectTypeError();
275
276 auto key = keyFormatter(typeNameStem(getRawName<MemberPtr>()));
277 if (!j.contains(key)) {
278 t.*MemberPtr = std::forward<D>(defaultValue);
279 return {};
280 }
281
282 decltype(auto) child = object_child_at(std::forward<J>(j), key);
283 return deserialize(t.*MemberPtr, std::forward<decltype(child)>(child), keyFormatter);
284}
285
286template <auto MemberPtr, class T, class J, IsKeyFormatter F>
287inline Expected<> member_deserialize_default_impl(T& t, J&& j, F const& keyFormatter) {
288 static_assert(!typeNameStem(getRawName<MemberPtr>()).empty(), "member name is empty");
289 if (!j.is_object()) return makeDeserObjectTypeError();
290
291 auto key = keyFormatter(typeNameStem(getRawName<MemberPtr>()));
292 if (!j.contains(key)) {
293 return {};
294 }
295
296 decltype(auto) child = object_child_at(std::forward<J>(j), key);
297 return deserialize(t.*MemberPtr, std::forward<decltype(child)>(child), keyFormatter);
298}
299
300template <ll::FixedString Key, bool AllowOptionalMissing, class T, class J, IsKeyFormatter F>
301inline Expected<> field_deserialize_impl(T& t, J&& j, F const& keyFormatter) {
302 static_assert(Key.size() != 0, "field name is empty");
303 if (!j.is_object()) return makeDeserObjectTypeError();
304
305 auto key = keyFormatter(Key.sv());
306 if (!j.contains(key)) {
307 if constexpr (AllowOptionalMissing && concepts::IsOptional<std::remove_cvref_t<T>>) {
308 t = std::nullopt;
309 return {};
310 } else {
311 return makeDeserMissingRequiredFieldError(std::string{key});
312 }
313 }
314
315 decltype(auto) child = object_child_at(std::forward<J>(j), key);
316 return deserialize(t, std::forward<decltype(child)>(child), keyFormatter);
317}
318
319template <ll::FixedString Key, class T, class D, class J, IsKeyFormatter F>
320inline Expected<> field_deserialize_or_impl(T& t, J&& j, D&& defaultValue, F const& keyFormatter) {
321 static_assert(Key.size() != 0, "field name is empty");
322 if (!j.is_object()) return makeDeserObjectTypeError();
323
324 auto key = keyFormatter(Key.sv());
325 if (!j.contains(key)) {
326 t = std::forward<D>(defaultValue);
327 return {};
328 }
329
330 decltype(auto) child = object_child_at(std::forward<J>(j), key);
331 return deserialize(t, std::forward<decltype(child)>(child), keyFormatter);
332}
333
334template <ll::FixedString Key, class T, class J, IsKeyFormatter F>
335inline Expected<> field_deserialize_default_impl(T& t, J&& j, F const& keyFormatter) {
336 static_assert(Key.size() != 0, "field name is empty");
337 if (!j.is_object()) return makeDeserObjectTypeError();
338
339 auto key = keyFormatter(Key.sv());
340 if (!j.contains(key)) {
341 return {};
342 }
343
344 decltype(auto) child = object_child_at(std::forward<J>(j), key);
345 return deserialize(t, std::forward<decltype(child)>(child), keyFormatter);
346}
347
348} // namespace
349
350template <auto MemberPtr, class T, class J, IsKeyFormatter F>
351inline Expected<> member_deserialize(T& t, J&& j, F const& keyFormatter) noexcept
352 requires(!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
353{
354 return member_deserialize_impl<MemberPtr, true>(t, std::forward<J>(j), keyFormatter);
355}
356
357template <auto MemberPtr, class T, class J, IsKeyFormatter F>
358inline Expected<> member_deserialize_required(T& t, J&& j, F const& keyFormatter) noexcept
359 requires(!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
360{
361 return member_deserialize_impl<MemberPtr, false>(t, std::forward<J>(j), keyFormatter);
362}
363
364template <auto MemberPtr, class T, class D, class J, IsKeyFormatter F>
365inline Expected<> member_deserialize_or(T& t, J&& j, D&& defaultValue, F const& keyFormatter) noexcept
366 requires(
368 && (!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
369 )
370{
371 return member_deserialize_or_impl<MemberPtr>(t, std::forward<J>(j), std::forward<D>(defaultValue), keyFormatter);
372}
373
374template <ll::FixedString Key, class T, class J, IsKeyFormatter F>
375inline Expected<> field_deserialize(T& t, J&& j, F const& keyFormatter) noexcept
376 requires(!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
377{
378 return field_deserialize_impl<Key, true>(t, std::forward<J>(j), keyFormatter);
379}
380
381template <ll::FixedString Key, class T, class J, IsKeyFormatter F>
382inline Expected<> field_deserialize_required(T& t, J&& j, F const& keyFormatter) noexcept
383 requires(!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
384{
385 return field_deserialize_impl<Key, false>(t, std::forward<J>(j), keyFormatter);
386}
387
388template <ll::FixedString Key, class T, class D, class J, IsKeyFormatter F>
389inline Expected<> field_deserialize_or(T& t, J&& j, D&& defaultValue, F const& keyFormatter) noexcept
390 requires(
392 && (!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
393 )
394{
395 return field_deserialize_or_impl<Key>(t, std::forward<J>(j), std::forward<D>(defaultValue), keyFormatter);
396}
397
398template <auto MemberPtr, class T, class J, IsKeyFormatter F>
399inline Expected<> member_deserialize(T& t, J const& j, F const& keyFormatter) noexcept {
400 return member_deserialize_impl<MemberPtr, true>(t, j, keyFormatter);
401}
402
403template <auto MemberPtr, class T, class J, IsKeyFormatter F>
404inline Expected<> member_deserialize_required(T& t, J const& j, F const& keyFormatter) noexcept {
405 return member_deserialize_impl<MemberPtr, false>(t, j, keyFormatter);
406}
407
408template <auto MemberPtr, class T, class D, class J, IsKeyFormatter F>
409inline Expected<> member_deserialize_or(T& t, J const& j, D&& defaultValue, F const& keyFormatter) noexcept
411{
412 return member_deserialize_or_impl<MemberPtr>(t, j, std::forward<D>(defaultValue), keyFormatter);
413}
414
415template <ll::FixedString Key, class T, class J, IsKeyFormatter F>
416inline Expected<> field_deserialize(T& t, J const& j, F const& keyFormatter) noexcept {
417 return field_deserialize_impl<Key, true>(t, j, keyFormatter);
418}
419
420template <ll::FixedString Key, class T, class J, IsKeyFormatter F>
421inline Expected<> field_deserialize_required(T& t, J const& j, F const& keyFormatter) noexcept {
422 return field_deserialize_impl<Key, false>(t, j, keyFormatter);
423}
424
425template <ll::FixedString Key, class T, class D, class J, IsKeyFormatter F>
426inline Expected<> field_deserialize_or(T& t, J const& j, D&& defaultValue, F const& keyFormatter) noexcept
428{
429 return field_deserialize_or_impl<Key>(t, j, std::forward<D>(defaultValue), keyFormatter);
430}
431
432template <auto MemberPtr, class T, class J>
433inline Expected<> member_deserialize(T& t, J&& j) noexcept
434 requires(!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
435{
436 return member_deserialize<MemberPtr>(t, std::forward<J>(j), detail::default_key_formatter);
437}
438
439template <auto MemberPtr, class T, class J>
440inline Expected<> member_deserialize_required(T& t, J&& j) noexcept
441 requires(!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
442{
443 return member_deserialize_required<MemberPtr>(t, std::forward<J>(j), detail::default_key_formatter);
444}
445
446template <auto MemberPtr, class T, class D, class J>
447inline Expected<> member_deserialize_or(T& t, J&& j, D&& defaultValue) noexcept
448 requires(
450 && (!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
451 )
452{
453 return member_deserialize_or<MemberPtr>(
454 t,
455 std::forward<J>(j),
456 std::forward<D>(defaultValue),
457 detail::default_key_formatter
458 );
459}
460
461template <ll::FixedString Key, class T, class J>
462inline Expected<> field_deserialize(T& t, J&& j) noexcept
463 requires(!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
464{
465 return field_deserialize<Key>(t, std::forward<J>(j), detail::default_key_formatter);
466}
467
468template <ll::FixedString Key, class T, class J>
469inline Expected<> field_deserialize_required(T& t, J&& j) noexcept
470 requires(!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
471{
472 return field_deserialize_required<Key>(t, std::forward<J>(j), detail::default_key_formatter);
473}
474
475template <ll::FixedString Key, class T, class D, class J>
476inline Expected<> field_deserialize_or(T& t, J&& j, D&& defaultValue) noexcept
477 requires(
479 && (!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
480 )
481{
482 return field_deserialize_or<Key>(
483 t,
484 std::forward<J>(j),
485 std::forward<D>(defaultValue),
486 detail::default_key_formatter
487 );
488}
489
490template <auto MemberPtr, class T, class J>
491inline Expected<> member_deserialize(T& t, J const& j) noexcept {
492 return member_deserialize_impl<MemberPtr, true>(t, j, detail::default_key_formatter);
493}
494
495template <auto MemberPtr, class T, class J>
496inline Expected<> member_deserialize_required(T& t, J const& j) noexcept {
497 return member_deserialize_impl<MemberPtr, false>(t, j, detail::default_key_formatter);
498}
499
500template <auto MemberPtr, class T, class D, class J>
501inline Expected<> member_deserialize_or(T& t, J const& j, D&& defaultValue) noexcept
503{
504 return member_deserialize_or_impl<MemberPtr>(t, j, std::forward<D>(defaultValue), detail::default_key_formatter);
505}
506
507template <ll::FixedString Key, class T, class J>
508inline Expected<> field_deserialize(T& t, J const& j) noexcept {
509 return field_deserialize_impl<Key, true>(t, j, detail::default_key_formatter);
510}
511
512template <ll::FixedString Key, class T, class J>
513inline Expected<> field_deserialize_required(T& t, J const& j) noexcept {
514 return field_deserialize_impl<Key, false>(t, j, detail::default_key_formatter);
515}
516
517template <ll::FixedString Key, class T, class D, class J>
518inline Expected<> field_deserialize_or(T& t, J const& j, D&& defaultValue) noexcept
520{
521 return field_deserialize_or_impl<Key>(t, j, std::forward<D>(defaultValue), detail::default_key_formatter);
522}
523
524template <auto MemberPtr, class T, class J, IsKeyFormatter F>
525inline Expected<> member(T& t, J&& j, F const& keyFormatter) noexcept
526 requires(!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
527{
528 return member_deserialize<MemberPtr>(t, std::forward<J>(j), keyFormatter);
529}
530
531template <auto MemberPtr, class T, class J, IsKeyFormatter F>
532inline Expected<> required_member(T& t, J&& j, F const& keyFormatter) noexcept
533 requires(!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
534{
535 return member_deserialize_required<MemberPtr>(t, std::forward<J>(j), keyFormatter);
536}
537
538template <auto MemberPtr, class T, class D, class J, IsKeyFormatter F>
539inline Expected<> default_member(T& t, J&& j, D&& defaultValue, F const& keyFormatter) noexcept
540 requires(
542 && (!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
543 )
544{
545 return member_deserialize_or<MemberPtr>(t, std::forward<J>(j), std::forward<D>(defaultValue), keyFormatter);
546}
547
548template <auto MemberPtr, class T, class J, IsKeyFormatter F>
549inline Expected<> default_member(T& t, J&& j, F const& keyFormatter) noexcept
550 requires(!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
551{
552 return member_deserialize_default_impl<MemberPtr>(t, std::forward<J>(j), keyFormatter);
553}
554
555template <ll::FixedString Key, class T, class J, IsKeyFormatter F>
556inline Expected<> field(T& t, J&& j, F const& keyFormatter) noexcept
557 requires(!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
558{
559 return field_deserialize<Key>(t, std::forward<J>(j), keyFormatter);
560}
561
562template <ll::FixedString Key, class T, class J, IsKeyFormatter F>
563inline Expected<> required_field(T& t, J&& j, F const& keyFormatter) noexcept
564 requires(!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
565{
566 return field_deserialize_required<Key>(t, std::forward<J>(j), keyFormatter);
567}
568
569template <ll::FixedString Key, class T, class D, class J, IsKeyFormatter F>
570inline Expected<> default_field(T& t, J&& j, D&& defaultValue, F const& keyFormatter) noexcept
571 requires(
573 && (!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
574 )
575{
576 return field_deserialize_or<Key>(t, std::forward<J>(j), std::forward<D>(defaultValue), keyFormatter);
577}
578
579template <ll::FixedString Key, class T, class J, IsKeyFormatter F>
580inline Expected<> default_field(T& t, J&& j, F const& keyFormatter) noexcept
581 requires(!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
582{
583 return field_deserialize_default_impl<Key>(t, std::forward<J>(j), keyFormatter);
584}
585
586template <auto MemberPtr, class T, class J>
587inline Expected<> member(T& t, J&& j) noexcept
588 requires(!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
589{
590 return member<MemberPtr>(t, std::forward<J>(j), detail::default_key_formatter);
591}
592
593template <auto MemberPtr, class T, class J>
594inline Expected<> required_member(T& t, J&& j) noexcept
595 requires(!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
596{
597 return required_member<MemberPtr>(t, std::forward<J>(j), detail::default_key_formatter);
598}
599
600template <auto MemberPtr, class T, class D, class J>
601inline Expected<> default_member(T& t, J&& j, D&& defaultValue) noexcept
602 requires(
604 && (!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
605 )
606{
607 return default_member<MemberPtr>(
608 t,
609 std::forward<J>(j),
610 std::forward<D>(defaultValue),
611 detail::default_key_formatter
612 );
613}
614
615template <auto MemberPtr, class T, class J>
616inline Expected<> default_member(T& t, J&& j) noexcept
617 requires(!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
618{
619 return member_deserialize_default_impl<MemberPtr>(t, std::forward<J>(j), detail::default_key_formatter);
620}
621
622template <ll::FixedString Key, class T, class J>
623inline Expected<> field(T& t, J&& j) noexcept
624 requires(!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
625{
626 return field<Key>(t, std::forward<J>(j), detail::default_key_formatter);
627}
628
629template <ll::FixedString Key, class T, class J>
630inline Expected<> required_field(T& t, J&& j) noexcept
631 requires(!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
632{
633 return required_field<Key>(t, std::forward<J>(j), detail::default_key_formatter);
634}
635
636template <ll::FixedString Key, class T, class D, class J>
637inline Expected<> default_field(T& t, J&& j, D&& defaultValue) noexcept
638 requires(
640 && (!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
641 )
642{
643 return default_field<Key>(t, std::forward<J>(j), std::forward<D>(defaultValue), detail::default_key_formatter);
644}
645
646template <ll::FixedString Key, class T, class J>
647inline Expected<> default_field(T& t, J&& j) noexcept
648 requires(!std::is_lvalue_reference_v<J&&> || std::is_const_v<std::remove_reference_t<J>>)
649{
650 return field_deserialize_default_impl<Key>(t, std::forward<J>(j), detail::default_key_formatter);
651}
652
653template <auto MemberPtr, class T, class J, IsKeyFormatter F>
654inline Expected<> member(T& t, J const& j, F const& keyFormatter) noexcept {
655 return member_deserialize<MemberPtr>(t, j, keyFormatter);
656}
657
658template <auto MemberPtr, class T, class J, IsKeyFormatter F>
659inline Expected<> required_member(T& t, J const& j, F const& keyFormatter) noexcept {
660 return member_deserialize_required<MemberPtr>(t, j, keyFormatter);
661}
662
663template <auto MemberPtr, class T, class D, class J, IsKeyFormatter F>
664inline Expected<> default_member(T& t, J const& j, D&& defaultValue, F const& keyFormatter) noexcept
666{
667 return member_deserialize_or<MemberPtr>(t, j, std::forward<D>(defaultValue), keyFormatter);
668}
669
670template <auto MemberPtr, class T, class J, IsKeyFormatter F>
671inline Expected<> default_member(T& t, J const& j, F const& keyFormatter) noexcept {
672 return member_deserialize_default_impl<MemberPtr>(t, j, keyFormatter);
673}
674
675template <ll::FixedString Key, class T, class J, IsKeyFormatter F>
676inline Expected<> field(T& t, J const& j, F const& keyFormatter) noexcept {
677 return field_deserialize<Key>(t, j, keyFormatter);
678}
679
680template <ll::FixedString Key, class T, class J, IsKeyFormatter F>
681inline Expected<> required_field(T& t, J const& j, F const& keyFormatter) noexcept {
682 return field_deserialize_required<Key>(t, j, keyFormatter);
683}
684
685template <ll::FixedString Key, class T, class D, class J, IsKeyFormatter F>
686inline Expected<> default_field(T& t, J const& j, D&& defaultValue, F const& keyFormatter) noexcept
688{
689 return field_deserialize_or<Key>(t, j, std::forward<D>(defaultValue), keyFormatter);
690}
691
692template <ll::FixedString Key, class T, class J, IsKeyFormatter F>
693inline Expected<> default_field(T& t, J const& j, F const& keyFormatter) noexcept {
694 return field_deserialize_default_impl<Key>(t, j, keyFormatter);
695}
696
697template <auto MemberPtr, class T, class J>
698inline Expected<> member(T& t, J const& j) noexcept {
699 return member<MemberPtr>(t, j, detail::default_key_formatter);
700}
701
702template <auto MemberPtr, class T, class J>
703inline Expected<> required_member(T& t, J const& j) noexcept {
704 return required_member<MemberPtr>(t, j, detail::default_key_formatter);
705}
706
707template <auto MemberPtr, class T, class D, class J>
708inline Expected<> default_member(T& t, J const& j, D&& defaultValue) noexcept
710{
711 return default_member<MemberPtr>(t, j, std::forward<D>(defaultValue), detail::default_key_formatter);
712}
713
714template <auto MemberPtr, class T, class J>
715inline Expected<> default_member(T& t, J const& j) noexcept {
716 return member_deserialize_default_impl<MemberPtr>(t, j, detail::default_key_formatter);
717}
718
719template <ll::FixedString Key, class T, class J>
720inline Expected<> field(T& t, J const& j) noexcept {
721 return field<Key>(t, j, detail::default_key_formatter);
722}
723
724template <ll::FixedString Key, class T, class J>
725inline Expected<> required_field(T& t, J const& j) noexcept {
726 return required_field<Key>(t, j, detail::default_key_formatter);
727}
728
729template <ll::FixedString Key, class T, class D, class J>
730inline Expected<> default_field(T& t, J const& j, D&& defaultValue) noexcept
732{
733 return default_field<Key>(t, j, std::forward<D>(defaultValue), detail::default_key_formatter);
734}
735
736template <ll::FixedString Key, class T, class J>
737inline Expected<> default_field(T& t, J const& j) noexcept {
738 return field_deserialize_default_impl<Key>(t, j, detail::default_key_formatter);
739}
740
741namespace {
742
743template <class T, class J, IsKeyFormatter F, size_t I = 0, class... Args>
744inline Expected<std::remove_cvref_t<T>> tuple_deserialize_value(J&& j, F const& keyFormatter, Args&&... args) {
745 using RT = std::remove_cvref_t<T>;
746 if constexpr (I == std::tuple_size_v<RT>) {
747 return RT{std::forward<Args>(args)...};
748 } else {
749 using element_type = std::remove_cvref_t<std::tuple_element_t<I, RT>>;
750 auto child = array_child_at<element_type>(std::forward<J>(j), I);
751 auto value = deserialize_construct<element_type>(std::forward<decltype(child)>(child), keyFormatter);
752 if (!value) {
753 return makeDeserIndexError(I, value.error());
754 }
755 return tuple_deserialize_value<RT, J, F, I + 1>(
756 std::forward<J>(j),
757 keyFormatter,
758 std::forward<Args>(args)...,
759 std::move(*value)
760 );
761 }
762}
763
764template <class T, class J, IsKeyFormatter F, size_t I = 0, class... Args>
765inline Expected<std::remove_cvref_t<T>> reflectable_deserialize_value(J&& j, F const& keyFormatter, Args&&... args) {
766 using RT = std::remove_cvref_t<T>;
767 if constexpr (I == member_count_v<RT>) {
768 return RT{std::forward<Args>(args)...};
769 } else {
770 using member_type = std::remove_cvref_t<member_t<I, RT>>;
771 auto key = keyFormatter(member_name_array_v<RT>[I]);
772 std::string sname{key};
773 if (!j.contains(sname)) {
774 if constexpr (concepts::IsOptional<member_type>) {
775 return reflectable_deserialize_value<RT, J, F, I + 1>(
776 std::forward<J>(j),
777 keyFormatter,
778 std::forward<Args>(args)...,
779 member_type{std::nullopt}
780 );
781 } else {
782 return makeDeserMissingRequiredFieldError(sname);
783 }
784 }
785
786 decltype(auto) child = object_child_at(std::forward<J>(j), sname);
787 auto value = deserialize_construct<member_type>(std::forward<decltype(child)>(child), keyFormatter);
788 if (!value) {
789 return makeDeserMemberError(sname, value.error());
790 }
791 return reflectable_deserialize_value<RT, J, F, I + 1>(
792 std::forward<J>(j),
793 keyFormatter,
794 std::forward<Args>(args)...,
795 std::move(*value)
796 );
797 }
798}
799
800// std::in_range rejects the character types on the MSVC STL, so the check is spelled out here.
801template <class RT>
802 requires(std::integral<RT>)
803constexpr bool isRepresentable(int64 value) noexcept {
804 if constexpr (std::is_signed_v<RT>) {
805 return value >= static_cast<int64>((std::numeric_limits<RT>::lowest)())
806 && value <= static_cast<int64>((std::numeric_limits<RT>::max)());
807 } else {
808 return value >= 0 && static_cast<uint64>(value) <= static_cast<uint64>((std::numeric_limits<RT>::max)());
809 }
810}
811
812template <class RT>
813 requires(std::integral<RT>)
814constexpr bool isRepresentable(uint64 value) noexcept {
815 return value <= static_cast<uint64>((std::numeric_limits<RT>::max)());
816}
817
818template <class RT>
819 requires(std::integral<RT> && !std::same_as<RT, bool>)
820inline Expected<RT> narrowIntegral(int64 value) {
821 if (!isRepresentable<RT>(value)) {
822 return makeDeserNumberRangeError(fmt::to_string(value), type_name_v<RT>);
823 }
824 return static_cast<RT>(value);
825}
826
827template <class RT>
828 requires(std::integral<RT> && !std::same_as<RT, bool>)
829inline Expected<RT> narrowIntegral(uint64 value) {
830 if (!isRepresentable<RT>(value)) {
831 return makeDeserNumberRangeError(fmt::to_string(value), type_name_v<RT>);
832 }
833 return static_cast<RT>(value);
834}
835
836template <class T, class J, IsKeyFormatter F>
837inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F const&, meta::PriorityTag<11>)
838 requires(std::is_arithmetic_v<std::remove_cvref_t<T>>)
839{
840 using RT = std::remove_cvref_t<T>;
841 if (!j.is_number() && !j.is_boolean()) return makeDeserArithmeticTypeError();
842
843 if constexpr (std::same_as<RT, bool>) {
844 return static_cast<RT>(j);
845 } else if constexpr (std::integral<RT> && !std::same_as<RT, bool>) {
846 if (!j.is_number()) return static_cast<RT>(static_cast<bool>(j));
847 if (j.is_number_float()) {
848 auto value = static_cast<double>(j);
849 if (std::trunc(value) != value) return makeDeserNumberFractionError(fmt::to_string(value));
850 // Both bounds are powers of two and therefore exact, so widening below cannot overflow and
851 // the remaining range check is left to narrowIntegral.
852 if constexpr (std::unsigned_integral<RT>) {
853 if (value < 0.0 || value >= std::ldexp(1.0, 64)) {
854 return makeDeserNumberRangeError(fmt::to_string(value), type_name_v<RT>);
855 }
856 return narrowIntegral<RT>(static_cast<uint64>(value));
857 } else {
858 if (value < -std::ldexp(1.0, 63) || value >= std::ldexp(1.0, 63)) {
859 return makeDeserNumberRangeError(fmt::to_string(value), type_name_v<RT>);
860 }
861 return narrowIntegral<RT>(static_cast<int64>(value));
862 }
863 }
864 if (j.is_number_unsigned()) return narrowIntegral<RT>(static_cast<uint64>(j));
865 return narrowIntegral<RT>(static_cast<int64>(j));
866 } else {
867 // Report values that would otherwise silently turn into an infinity.
868 if (j.is_number_float()) {
869 auto value = static_cast<double>(j);
870 if (std::abs(value) > static_cast<double>((std::numeric_limits<RT>::max)())) {
871 return makeDeserNumberRangeError(fmt::to_string(value), type_name_v<RT>);
872 }
873 }
874 return static_cast<RT>(j);
875 }
876}
877
878template <class T, class J, IsKeyFormatter F>
879inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F const& keyFormatter, meta::PriorityTag<10>)
880 requires(
881 detail::has_value_deserializer_v<std::remove_cvref_t<T>, J, F>
882 || detail::is_string_serializable_v<std::remove_cvref_t<T>>
883 )
884{
885 using RT = std::remove_cvref_t<T>;
886 if constexpr (detail::has_value_deserializer_v<RT, J, F>) {
887 using JT = std::remove_cvref_t<J>;
888 decltype(auto) result = [&]() -> decltype(auto) {
889 if constexpr (requires { Serializer<RT, JT>::deserialize(std::forward<J>(j), keyFormatter); }) {
890 return Serializer<RT, JT>::deserialize(std::forward<J>(j), keyFormatter);
891 } else if constexpr (requires { Serializer<RT, JT>::deserialize(std::forward<J>(j)); }) {
892 return Serializer<RT, JT>::deserialize(std::forward<J>(j));
893 } else if constexpr (requires { Serializer<RT>::deserialize(std::forward<J>(j), keyFormatter); }) {
894 return Serializer<RT>::deserialize(std::forward<J>(j), keyFormatter);
895 } else if constexpr (requires { Serializer<RT>::deserialize(std::forward<J>(j)); }) {
896 return Serializer<RT>::deserialize(std::forward<J>(j));
897 } else if constexpr (requires {
898 Serializer<RT>::template deserialize<JT>(std::forward<J>(j), keyFormatter);
899 }) {
900 return Serializer<RT>::template deserialize<JT>(std::forward<J>(j), keyFormatter);
901 } else {
902 return Serializer<RT>::template deserialize<JT>(std::forward<J>(j));
903 }
904 }();
905 using Result = std::remove_cvref_t<decltype(result)>;
906 if constexpr (concepts::IsLeviExpected<Result>) {
907 if (!result) return forwardError(result.error());
908 return std::move(*result);
909 } else {
910 return std::forward<decltype(result)>(result);
911 }
912 } else {
913 if (!j.is_string()) return makeDeserStringTypeError();
914 if constexpr (std::is_lvalue_reference_v<J&&> && concepts::BorrowableStringSource<J>) {
915 auto const& text = std::as_const(j).template get_ref<typename std::remove_cvref_t<J>::string_t const&>();
916 if (auto res = Serializer<RT>::from_string(std::string_view{text}); res) {
917 return *std::move(res);
918 } else {
919 return forwardError(res.error());
920 }
921 } else {
922 std::string text = std::string{std::forward<J>(j)};
923 if (auto res = Serializer<RT>::from_string(text); res) {
924 return *std::move(res);
925 } else {
926 return forwardError(res.error());
927 }
928 }
929 }
930}
931
932template <class T, class J, IsKeyFormatter F>
933inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F const& keyFormatter, meta::PriorityTag<9>)
934 requires(concepts::IsOptional<std::remove_cvref_t<T>>)
935{
936 using RT = std::remove_cvref_t<T>;
937 using value_type = typename RT::value_type;
938 if (j.is_null()) {
939 return RT{std::nullopt};
940 }
941 auto value = deserialize_construct<value_type>(std::forward<J>(j), keyFormatter);
942 if (!value) return forwardError(value.error());
943 return RT{std::move(*value)};
944}
945
946template <class T, class J, IsKeyFormatter F>
947inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F const& keyFormatter, meta::PriorityTag<9>)
948 requires(concepts::IsDispatcher<std::remove_cvref_t<T>>)
949{
950 using RT = std::remove_cvref_t<T>;
951 using storage_type = typename RT::storage_type;
952 auto storage = deserialize_construct<storage_type>(std::forward<J>(j), keyFormatter);
953 if (!storage) return forwardError(storage.error());
954 RT result{std::move(*storage)};
955 result.call();
956 return result;
957}
958
959template <class T, class J, IsKeyFormatter F>
960inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F const& keyFormatter, meta::PriorityTag<8>)
961 requires(concepts::IsVectorBase<std::remove_cvref_t<T>>)
962{
963 using RT = std::remove_cvref_t<T>;
964 if (!j.is_array()) return makeDeserArrayTypeError();
965 RT result{};
966 Expected<> res;
967 RT::forEachComponent([&]<typename axis_type, size_t iter> {
968 if (res) {
969 auto child = array_child_at<axis_type>(std::forward<J>(j), iter);
970 auto value = deserialize_construct<axis_type>(std::forward<decltype(child)>(child), keyFormatter);
971 if (!value) {
972 res = makeDeserIndexError(iter, value.error());
973 } else {
974 result.template get<axis_type, iter>() = std::move(*value);
975 }
976 }
977 });
978 if (!res) return forwardError(res.error());
979 return result;
980}
981
982template <class T, class J, IsKeyFormatter F>
983inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F const& keyFormatter, meta::PriorityTag<7>)
984 requires(std::is_enum_v<std::remove_cvref_t<T>>)
985{
986 using enum_type = std::remove_cvref_t<T>;
987 if (j.is_string()) {
988 std::string s = std::string{std::forward<J>(j)};
989 if (auto res = detail::string_to_enum<enum_type>(s, keyFormatter)) {
990 return *res;
991 } else if constexpr (magic_enum::detail::subtype_v<enum_type> == magic_enum::detail::enum_subtype::flags) {
992 return makeDeserEnumFlagsValueError(s);
993 } else {
994 return makeDeserEnumValueError(s);
995 }
996 } else if (j.is_number()) {
997 return static_cast<enum_type>(static_cast<std::underlying_type_t<enum_type>>(j));
998 } else {
999 return makeDeserEnumTypeError();
1000 }
1001}
1002
1003template <class T, class J, IsKeyFormatter F>
1004inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F const& keyFormatter, meta::PriorityTag<6>)
1005 requires(concepts::IsVariant<std::remove_cvref_t<T>>)
1006{
1007 using RT = std::remove_cvref_t<T>;
1008 std::optional<RT> matched;
1009
1010 [&]<typename... Ts>(std::type_identity<std::variant<Ts...>>) {
1011 (
1012 [&] {
1013 if (matched.has_value()) return;
1014 if constexpr (std::is_arithmetic_v<Ts>) {
1015 Expected<Ts> value = [&]() -> Expected<Ts> {
1016 if constexpr (std::same_as<Ts, bool>) {
1017 if (j.is_boolean()) return j.template get<bool>();
1018 } else if constexpr (std::is_floating_point_v<Ts>) {
1019 if (j.is_number_float()) {
1020 auto number = j.template get<double>();
1021 if (std::abs(number) <= static_cast<double>((std::numeric_limits<Ts>::max)())) {
1022 return static_cast<Ts>(number);
1023 }
1024 }
1025 } else if constexpr (std::is_signed_v<Ts>) {
1026 if (j.is_number_integer() && !j.is_number_unsigned()) {
1027 auto number = j.template get<int64>();
1028 if (isRepresentable<Ts>(number)) return static_cast<Ts>(number);
1029 }
1030 } else if constexpr (std::is_unsigned_v<Ts>) {
1031 if (j.is_number_unsigned()) {
1032 auto number = j.template get<uint64>();
1033 if (isRepresentable<Ts>(number)) return static_cast<Ts>(number);
1034 }
1035 }
1036 return makeDeserNumberTypeError(j.type_name());
1037 }();
1038 if (value) {
1039 matched.emplace(std::in_place_type<Ts>, std::move(*value));
1040 }
1041 }
1042 }(),
1043 ...);
1044 }(std::type_identity<RT>{});
1045
1046 [&]<typename... Ts>(std::type_identity<std::variant<Ts...>>) {
1047 (
1048 [&] {
1049 if (matched.has_value()) return;
1050 if (auto value = deserialize_construct<Ts>(std::forward<J>(j), keyFormatter); value) {
1051 matched.emplace(std::in_place_type<Ts>, std::move(*value));
1052 }
1053 }(),
1054 ...);
1055 }(std::type_identity<RT>{});
1056
1057 if (!matched) return makeDeserVariantCastError(j.type_name(), j.dump());
1058 return std::move(*matched);
1059}
1060
1061template <class T, class J, IsKeyFormatter F>
1062inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F const&, meta::PriorityTag<5>)
1063 requires(
1064 concepts::IsString<std::remove_cvref_t<T>> && std::is_assignable_v<std::remove_cvref_t<T>&, std::string>
1065 && !std::same_as<std::remove_cvref_t<T>, std::string_view>
1066 )
1067{
1068 using RT = std::remove_cvref_t<T>;
1069 if (!j.is_string()) return makeDeserStringTypeError();
1070 return RT{std::string{std::forward<J>(j)}};
1071}
1072
1073template <class T, class J, IsKeyFormatter F>
1074inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F const&, meta::PriorityTag<5>)
1075 requires(std::same_as<std::remove_cvref_t<T>, std::string_view>)
1076{
1077 if (!j.is_string()) return makeDeserStringTypeError();
1078 if constexpr (std::is_lvalue_reference_v<J&&> && concepts::BorrowableStringSource<J>) {
1079 auto const& text = std::as_const(j).template get_ref<typename std::remove_cvref_t<J>::string_t const&>();
1080 return std::string_view{text};
1081 } else {
1082 return makeDeserStringViewLifetimeError();
1083 }
1084}
1085
1086template <class T, class J, IsKeyFormatter F>
1087inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F const& keyFormatter, meta::PriorityTag<4>)
1088 requires(concepts::TupleLike<std::remove_cvref_t<T>>)
1089{
1090 using RT = std::remove_cvref_t<T>;
1091 if (!j.is_array()) return makeDeserArrayTypeError();
1092 if (j.size() != std::tuple_size_v<RT>) return makeDeserArraySizeError(std::tuple_size_v<RT>);
1093 return tuple_deserialize_value<RT>(std::forward<J>(j), keyFormatter);
1094}
1095
1096template <class T, class J, IsKeyFormatter F>
1097inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F const& keyFormatter, meta::PriorityTag<3>)
1098 requires(concepts::ArrayLike<std::remove_cvref_t<T>>)
1099{
1100 using RT = std::remove_cvref_t<T>;
1101 using value_type = typename RT::value_type;
1102 if (!j.is_array()) return makeDeserArrayTypeError();
1103 RT result{};
1104 if constexpr (requires(RT& a) { a.clear(); }) {
1105 result.clear();
1106 }
1107 for (size_t i = 0; i < j.size(); ++i) {
1108 auto child = array_child_at<value_type>(std::forward<J>(j), i);
1109 auto value = deserialize_construct<value_type>(std::forward<decltype(child)>(child), keyFormatter);
1110 if (!value) return makeDeserIndexError(i, value.error());
1111 array_append_value(result, std::move(*value));
1112 }
1113 return result;
1114}
1115
1116template <class T, class J, IsKeyFormatter F>
1117inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F const& keyFormatter, meta::PriorityTag<2>)
1118 requires(concepts::Associative<std::remove_cvref_t<T>>)
1119{
1120 using RT = std::remove_cvref_t<T>;
1121 static_assert(
1122 detail::is_key_stringifiable_v<typename RT::key_type>,
1123 "an associative container key has to be a string, an enum, or a type with a "
1124 "ll::reflection::Serializer<T>::to_string / from_string specialization"
1125 );
1126 J const& jConst = j;
1127 if (!jConst.is_object()) return makeDeserObjectTypeError();
1128 RT result{};
1129 if constexpr (requires(RT& a) { a.clear(); }) {
1130 result.clear();
1131 }
1132 for (auto&& [k, v] : jConst.items()) {
1133 std::string keyString{k};
1134 auto keyOpt = string_to_type<typename RT::key_type>(keyString, keyFormatter);
1135 if (!keyOpt.has_value()) {
1136 auto error = makeDeserInvalidKeyError(keyString);
1137 return makeDeserKeyError(keyString, error.error());
1138 }
1139 using mapped_type = typename RT::mapped_type;
1140 auto value = deserialize_construct<mapped_type>(std::forward<decltype(v)>(v), keyFormatter);
1141 if (!value) return makeDeserKeyError(keyString, value.error());
1142 associative_insert_value(result, std::move(*keyOpt), std::move(*value));
1143 }
1144 return result;
1145}
1146
1147template <class T, class J, IsKeyFormatter F>
1148inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F const& keyFormatter, meta::PriorityTag<1>)
1150{
1151 using RT = std::remove_cvref_t<T>;
1152 J const& jConst = j;
1153 if (!jConst.is_object()) return makeDeserObjectTypeError();
1154 return reflectable_deserialize_value<RT>(std::forward<J>(j), keyFormatter);
1155}
1156
1157template <class T, class J, class F>
1158constexpr bool use_convertible_deserialize_fallback_v =
1159 !std::is_arithmetic_v<std::remove_cvref_t<T>> && !detail::has_value_deserializer_v<std::remove_cvref_t<T>, J, F>
1160 && !concepts::IsOptional<std::remove_cvref_t<T>> && !concepts::IsDispatcher<std::remove_cvref_t<T>>
1161 && !concepts::IsVectorBase<std::remove_cvref_t<T>> && !std::is_enum_v<std::remove_cvref_t<T>>
1162 && !concepts::IsVariant<std::remove_cvref_t<T>>
1163 && !(concepts::IsString<std::remove_cvref_t<T>> && std::is_assignable_v<std::remove_cvref_t<T>&, std::string>)
1164 && !std::same_as<std::remove_cvref_t<T>, std::string_view> && !concepts::TupleLike<std::remove_cvref_t<T>>
1165 && !concepts::ArrayLike<std::remove_cvref_t<T>> && !concepts::Associative<std::remove_cvref_t<T>>
1166 && !Reflectable<std::remove_cvref_t<T>> && std::convertible_to<J, std::remove_cvref_t<T>>;
1167
1168template <class T, class J, IsKeyFormatter F>
1169inline Expected<std::remove_cvref_t<T>> deserialize_impl(J&& j, F const&, meta::PriorityTag<0>) {
1170 using RT = std::remove_cvref_t<T>;
1171 if constexpr (use_convertible_deserialize_fallback_v<T, J, F>) {
1172 return static_cast<RT>(j);
1173 } else {
1174 static_assert(
1175 traits::always_false<RT>,
1176 "cannot deserialize this type: provide a ll::reflection::Serializer<T> specialization, or use an "
1177 "arithmetic type, a string, an optional, a dispatcher, an enum, a variant, a tuple-like, an array-like "
1178 "or associative container, or a reflectable aggregate"
1179 );
1180 }
1181}
1182
1183} // namespace
1184
1185} // namespace ll::reflection
Definition Reflection.h:265
Definition Reflection.h:33
Definition Serializer.h:9