48namespace JsonReflector {
55 return size > std::numeric_limits<RAPIDJSON_NAMESPACE::SizeType>::max() ? std::numeric_limits<RAPIDJSON_NAMESPACE::SizeType>::max()
56 :
static_cast<RAPIDJSON_NAMESPACE::SizeType
>(size);
64 RAPIDJSON_NAMESPACE::StringBuffer buffer;
65 RAPIDJSON_NAMESPACE::Writer<RAPIDJSON_NAMESPACE::StringBuffer> writer(buffer);
66 document.Accept(writer);
75 RAPIDJSON_NAMESPACE::Document document(RAPIDJSON_NAMESPACE::kObjectType);
76 const RAPIDJSON_NAMESPACE::ParseResult parseRes = document.Parse(json, jsonSize);
77 if (parseRes.IsError()) {
84template <
typename Type>
85using IsBuiltInType = Traits::Any<std::is_integral<Type>, std::is_floating_point<Type>, std::is_pointer<Type>, std::is_enum<Type>,
86 Traits::IsSpecializingAnyOf<Type, std::tuple, std::pair>, Traits::IsIteratable<Type>,
87 Traits::IsSpecializingAnyOf<Type, std::unique_ptr, std::shared_ptr, std::weak_ptr, std::optional>,
IsVariant<Type>>;
88template <
typename Type>
using IsCustomType = Traits::Not<IsBuiltInType<Type>>;
92template <
typename Type>
101template <
typename Type, Traits::DisableIf<IsBuiltInType<Type>> * =
nullptr>
102void push(
const Type &reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator);
107template <
typename Type, Traits::DisableIf<IsJsonSerializable<Type>> * =
nullptr>
108void push(
const Type &reflectable, RAPIDJSON_NAMESPACE::Value::Array &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator);
113template <
typename Type, Traits::EnableIf<IsJsonSerializable<Type>> * =
nullptr>
114void push(
const Type &reflectable, RAPIDJSON_NAMESPACE::Value::Array &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator);
119template <
typename Type, Traits::EnableIf<IsJsonSerializable<Type>> * =
nullptr>
121 const Type &reflectable,
const char *name, RAPIDJSON_NAMESPACE::Value::Object &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator);
126template <
typename Type, Traits::DisableIf<IsJsonSerializable<Type>> * =
nullptr>
128 const Type &reflectable,
const char *name, RAPIDJSON_NAMESPACE::Value::Object &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator);
134template <
typename Type, Traits::DisableIf<IsBuiltInType<Type>> * =
nullptr>
135void push(
const Type &reflectable, RAPIDJSON_NAMESPACE::Value::Object &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator);
140template <
typename Type, Traits::DisableIf<IsBuiltInType<Type>> *>
141inline void push(
const Type &reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
144 RAPIDJSON_NAMESPACE::Value::Object obj(value.GetObject());
145 push(reflectable, obj, allocator);
151template <
typename Type,
153 Traits::All<std::is_integral<Type>, Traits::Not<std::is_same<Type, std::uint8_t>>, Traits::Not<std::is_same<Type, std::int8_t>>>,
154 std::is_floating_point<Type>> * =
nullptr>
155inline void push(Type reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
157 value.Set(reflectable, allocator);
163template <
typename Type, Traits::EnableIfAny<std::is_same<Type, std::u
int8_t>, std::is_same<Type, std::
int8_t>> * =
nullptr>
164inline void push(Type reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
166 value.Set(
static_cast<int>(reflectable), allocator);
172template <
typename Type, Traits::EnableIfAny<std::is_enum<Type>> * =
nullptr>
173inline void push(Type reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
175 value.Set(
static_cast<Traits::Conditional<std::is_unsigned<typename std::underlying_type<Type>::type
>, std::uint64_t, std::int64_t>>(reflectable),
182template <
typename Type, Traits::EnableIfAny<std::is_same<Type, const
char *>, std::is_same<Type, const
char *const &>> * =
nullptr>
183inline void push(Type reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
186 value.SetString(reflectable, allocator);
195template <
typename Type, Traits::EnableIf<std::is_same<Type, std::
string_view>> * =
nullptr>
196inline void push(Type reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
198 if (reflectable.data()) {
199 value.SetString(reflectable.data(),
rapidJsonSize(reflectable.size()), allocator);
208template <
typename Type, Traits::EnableIf<std::is_same<Type, std::
string>> * =
nullptr>
209inline void push(
const Type &reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
211 value.SetString(reflectable.data(),
rapidJsonSize(reflectable.size()), allocator);
217template <
typename Type, Traits::EnableIf<IsArrayOrSet<Type>, Traits::HasSize<Type>> * =
nullptr>
218void push(
const Type &reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
221 RAPIDJSON_NAMESPACE::Value::Array array(value.GetArray());
223 for (
const auto &item : reflectable) {
224 push(item, array, allocator);
231template <
typename Type, Traits::EnableIf<IsArrayOrSet<Type>, Traits::Not<Traits::HasSize<Type>>> * =
nullptr>
232void push(
const Type &reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
235 RAPIDJSON_NAMESPACE::Value::Array array(value.GetArray());
236 for (
const auto &item : reflectable) {
237 push(item, array, allocator);
244template <
typename Type, Traits::EnableIfAny<IsMapOrHash<Type>> * =
nullptr>
245void push(
const Type &reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
248 RAPIDJSON_NAMESPACE::Value::Object object(value.GetObject());
249 for (
const auto &item : reflectable) {
250 push(item.second, item.first.data(),
object, allocator);
257template <
typename Type, Traits::EnableIfAny<IsMultiMapOrHash<Type>> * =
nullptr>
258void push(
const Type &reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
261 for (
const auto &item : reflectable) {
262 const auto memberName = RAPIDJSON_NAMESPACE::Value::StringRefType(item.first.data(),
rapidJsonSize(item.first.size()));
263 const auto existingMember = value.FindMember(memberName);
264 const auto arrayAlreadyExists
265 = existingMember != value.MemberEnd() && existingMember->value.GetType() == RAPIDJSON_NAMESPACE::Type::kArrayType;
266 auto newArrayValue = RAPIDJSON_NAMESPACE::Value{ RAPIDJSON_NAMESPACE::kArrayType };
267 RAPIDJSON_NAMESPACE::Value::Array array = arrayAlreadyExists ? existingMember->value.GetArray() : newArrayValue.GetArray();
268 push(item.second, array, allocator);
269 if (!arrayAlreadyExists) {
270 value.AddMember(memberName, newArrayValue, allocator);
281 static void push(
const Tuple &tuple, RAPIDJSON_NAMESPACE::Value::Array &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
289 static void push(
const Tuple &tuple, RAPIDJSON_NAMESPACE::Value::Array &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
299template <
typename Type, Traits::EnableIf<Traits::IsSpecializationOf<Type, std::tuple>> * =
nullptr>
300void push(
const Type &reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
303 RAPIDJSON_NAMESPACE::Value::Array array(value.GetArray());
304 array.Reserve(std::tuple_size<Type>::value, allocator);
311template <
typename Type, Traits::EnableIf<Traits::IsSpecializationOf<Type, std::pair>> * =
nullptr>
312void push(
const Type &reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
315 RAPIDJSON_NAMESPACE::Value::Array array(value.GetArray());
316 array.Reserve(2, allocator);
317 push(reflectable.first, array, allocator);
318 push(reflectable.second, array, allocator);
324template <
typename Type,
325 Traits::EnableIfAny<Traits::IsSpecializingAnyOf<Type, std::unique_ptr, std::shared_ptr, std::weak_ptr, std::optional>> * =
nullptr>
326void push(
const Type &reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
332 push(*reflectable, value, allocator);
338template <
typename Type, Traits::EnableIf<IsVariant<Type>> * =
nullptr>
339void push(
const Type &reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
341 if (reflectable.valueless_by_exception()) {
346 RAPIDJSON_NAMESPACE::Value index, data;
347 index.SetUint64(reflectable.index());
349 [&data, &allocator](
const auto &reflectableOfActualType) {
350 if constexpr (!std::is_same_v<std::decay_t<
decltype(reflectableOfActualType)>, std::monostate>) {
351 push(reflectableOfActualType, data, allocator);
353 CPP_UTILITIES_UNUSED(data)
354 CPP_UTILITIES_UNUSED(allocator)
360 value.AddMember(
"index", index, allocator);
361 value.AddMember(
"data", data, allocator);
367template <
typename Type, Traits::EnableIf<IsJsonSerializable<Type>> *>
368void push(
const Type &reflectable, RAPIDJSON_NAMESPACE::Value::Array &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
370 RAPIDJSON_NAMESPACE::Value objectValue(RAPIDJSON_NAMESPACE::kObjectType);
371 RAPIDJSON_NAMESPACE::Value::Object object(objectValue.GetObject());
372 push(reflectable,
object, allocator);
373 value.PushBack(objectValue, allocator);
379template <
typename Type, Traits::DisableIf<IsJsonSerializable<Type>> *>
380void push(
const Type &reflectable, RAPIDJSON_NAMESPACE::Value::Array &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
382 RAPIDJSON_NAMESPACE::Value genericValue;
383 push(reflectable, genericValue, allocator);
384 value.PushBack(genericValue, allocator);
390template <
typename Type, Traits::EnableIf<IsJsonSerializable<Type>> *>
392 const Type &reflectable,
const char *name, RAPIDJSON_NAMESPACE::Value::Object &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
394 RAPIDJSON_NAMESPACE::Value objectValue(RAPIDJSON_NAMESPACE::kObjectType);
395 RAPIDJSON_NAMESPACE::Value::Object object(objectValue.GetObject());
396 push(reflectable,
object, allocator);
397 value.AddMember(RAPIDJSON_NAMESPACE::StringRef(name), objectValue, allocator);
403template <
typename Type, Traits::DisableIf<IsJsonSerializable<Type>> *>
405 const Type &reflectable,
const char *name, RAPIDJSON_NAMESPACE::Value::Object &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
407 RAPIDJSON_NAMESPACE::Value genericValue;
408 push(reflectable, genericValue, allocator);
409 value.AddMember(RAPIDJSON_NAMESPACE::StringRef(name), genericValue, allocator);
418template <
typename Type, Traits::DisableIf<IsBuiltInType<Type>> * =
nullptr>
419void pull(Type &reflectable,
const RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>>::ConstObject &value,
420 JsonDeserializationErrors *errors);
425template <
typename Type, Traits::DisableIf<IsBuiltInType<Type>> * =
nullptr>
426void pull(Type &reflectable,
const RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors);
431template <
typename Type, Traits::EnableIf<IsArrayOrSet<Type>, Traits::Not<Traits::IsReservable<Type>>> * =
nullptr>
432void pull(Type &reflectable,
const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors);
437template <
typename Type, Traits::EnableIf<IsArrayOrSet<Type>, Traits::IsReservable<Type>> * =
nullptr>
438void pull(Type &reflectable,
const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors);
443template <
typename Type, Traits::EnableIf<IsArray<Type>> * =
nullptr>
444void pull(Type &reflectable, rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>>::ConstArray array, JsonDeserializationErrors *errors);
449template <
typename Type, Traits::EnableIf<IsSet<Type>> * =
nullptr>
450void pull(Type &reflectable, rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>>::ConstArray array, JsonDeserializationErrors *errors);
455template <
typename Type, Traits::EnableIf<IsMultiSet<Type>> * =
nullptr>
456void pull(Type &reflectable, rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>>::ConstArray array, JsonDeserializationErrors *errors);
461template <
typename Type, Traits::EnableIf<IsMapOrHash<Type>> * =
nullptr>
462void pull(Type &reflectable,
const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors);
467template <
typename Type, Traits::EnableIf<IsMultiMapOrHash<Type>> * =
nullptr>
468void pull(Type &reflectable,
const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors);
473template <
typename Type, Traits::EnableIf<Traits::IsSpecializationOf<Type, std::tuple>> * =
nullptr>
474void pull(Type &reflectable,
const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors);
479template <
typename Type, Traits::EnableIf<Traits::IsSpecializationOf<Type, std::pair>> * =
nullptr>
480void pull(Type &reflectable,
const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors);
485template <
typename Type, Traits::EnableIf<Traits::IsSpecializationOf<Type, std::unique_ptr>> * =
nullptr>
486void pull(Type &reflectable,
const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors);
491template <
typename Type, Traits::EnableIf<Traits::IsSpecializationOf<Type, std::shared_ptr>> * =
nullptr>
492void pull(Type &reflectable,
const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors);
497template <
typename Type, Traits::EnableIf<Traits::IsSpecializationOf<Type, std::optional>> * =
nullptr>
498void pull(Type &reflectable,
const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors);
503template <
typename Type, Traits::EnableIf<IsVariant<Type>> * =
nullptr>
504void pull(Type &reflectable,
const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors);
509template <
typename Type>
511 Type &reflectable, rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>>::ValueIterator &value, JsonDeserializationErrors *errors);
518template <
typename Type>
519inline void pull(Type &reflectable,
const char *name,
const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>>::ConstObject &value,
520 JsonDeserializationErrors *errors);
525template <
typename Type, Traits::DisableIf<IsBuiltInType<Type>> *>
526void pull(Type &reflectable,
const RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors);
531template <
typename Type,
532 Traits::EnableIf<Traits::Not<std::is_same<Type, bool>>, Traits::Not<std::is_same<Type, std::uint8_t>>,
533 Traits::Not<std::is_same<Type, std::int8_t>>, Traits::Any<std::is_integral<Type>, std::is_floating_point<Type>>> * =
nullptr>
535 Type &reflectable,
const RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value,
JsonDeserializationErrors *errors)
537 if (!value.IsNumber()) {
543 reflectable = value.Is<Type>() ? value.Get<Type>() :
static_cast<Type
>(value.GetDouble());
549template <
typename Type, Traits::EnableIfAny<std::is_same<Type, std::u
int8_t>, std::is_same<Type, std::
int8_t>> * =
nullptr>
551 Type &reflectable,
const RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value,
JsonDeserializationErrors *errors)
554 pull(i, value, errors);
555 if (value.IsNumber()) {
556 reflectable =
static_cast<Type
>(i);
563template <
typename Type, Traits::EnableIf<std::is_same<Type,
bool>> * =
nullptr>
565 Type &reflectable,
const RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors)
567 if (!value.IsBool()) {
569 errors->reportTypeMismatch<Type>(value.GetType());
573 reflectable = value.GetBool();
580template <
typename Type, Traits::EnableIfAny<std::is_enum<Type>> * =
nullptr>
582 Type &reflectable,
const RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors)
584 using ExpectedType = Traits::Conditional<std::is_unsigned<typename std::underlying_type<Type>::type>, std::uint64_t, std::int64_t>;
585 if (!value.Is<ExpectedType>()) {
587 errors->reportTypeMismatch<ExpectedType>(value.GetType());
591 reflectable =
static_cast<Type
>(value.Get<ExpectedType>());
597template <
typename Type, Traits::EnableIf<std::is_same<Type, std::
string>> * =
nullptr>
599 Type &reflectable,
const RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors)
601 if (!value.IsString()) {
603 errors->reportTypeMismatch<std::string>(value.GetType());
607 reflectable = value.GetString();
614template <
typename Type,
615 Traits::EnableIfAny<std::is_same<Type, const char *>, std::is_same<Type, const char *const &>, std::is_same<Type, std::string_view>> * =
nullptr>
616inline void pull(Type &,
const RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors)
618 if (!value.IsString()) {
620 errors->reportTypeMismatch<std::string>(value.GetType());
629template <
typename Type, Traits::EnableIf<IsArrayOrSet<Type>, Traits::Not<Traits::IsReservable<Type>>> *>
632 if (!value.IsArray()) {
638 pull(reflectable, value.GetArray(), errors);
644template <
typename Type, Traits::EnableIf<IsArrayOrSet<Type>, Traits::IsReservable<Type>> *>
647 if (!value.IsArray()) {
653 auto array = value.GetArray();
654 reflectable.reserve(array.Size());
655 pull(reflectable, array, errors);
661template <
typename Type, Traits::EnableIf<IsArray<Type>> *>
668 std::size_t index = 0;
669 for (
const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &item : array) {
675 reflectable.emplace_back();
676 pull(reflectable.back(), item, errors);
688template <
typename Type, Traits::EnableIf<IsMultiSet<Type>> *>
695 std::size_t index = 0;
696 for (
const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &item : array) {
702 typename Type::value_type itemObj;
703 pull(itemObj, item, errors);
704 reflectable.emplace(std::move(itemObj));
716template <
typename Type, Traits::EnableIf<IsSet<Type>> *>
717void pull(Type &reflectable, rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>>::ConstArray array, JsonDeserializationErrors *errors)
723 std::size_t index = 0;
724 for (
const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &item : array) {
727 errors->currentIndex = index;
730 typename Type::value_type itemObj;
731 pull(itemObj, item, errors);
732 if (!reflectable.emplace(std::move(itemObj)).second) {
746template <
typename Type, Traits::EnableIf<IsMapOrHash<Type>> *>
747void pull(Type &reflectable,
const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors)
749 if (!value.IsObject()) {
751 errors->reportTypeMismatch<Type>(value.GetType());
755 auto obj = value.GetObject();
756 for (
auto i = obj.MemberBegin(), end = obj.MemberEnd(); i != end; ++i) {
757 pull(reflectable[i->name.GetString()], i->value, errors);
764template <
typename Type, Traits::EnableIf<IsMultiMapOrHash<Type>> *>
765void pull(Type &reflectable,
const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors)
767 if (!value.IsObject()) {
769 errors->reportTypeMismatch<Type>(value.GetType());
773 auto obj = value.GetObject();
774 for (
auto i = obj.MemberBegin(), end = obj.MemberEnd(); i != end; ++i) {
775 if (i->value.GetType() != RAPIDJSON_NAMESPACE::kArrayType) {
776 auto insertedIterator = reflectable.insert(
typename Type::value_type(i->name.GetString(),
typename Type::mapped_type()));
777 pull(insertedIterator->second, i->value, errors);
780 const auto array = i->value.GetArray();
781 for (
const auto &arrayValue : array) {
782 auto insertedIterator = reflectable.insert(
typename Type::value_type(i->name.GetString(),
typename Type::mapped_type()));
783 pull(insertedIterator->second, arrayValue, errors);
798 JsonReflector::pull<
typename std::tuple_element<N - 1, Tuple>::type>(std::get<N - 1>(tuple), value[N - 1], errors);
805 JsonReflector::pull<typename std::tuple_element<0, Tuple>::type>(std::get<0>(tuple), value[0], errors);
813template <
typename Type, Traits::EnableIf<Traits::IsSpecializationOf<Type, std::tuple>> *>
816 if (!value.IsArray()) {
822 const auto array = value.GetArray();
823 if (array.Size() != std::tuple_size<Type>::value) {
830 Detail::TuplePullHelper<Type, std::tuple_size<Type>::value>
::pull(reflectable, array, errors);
836template <
typename Type, Traits::EnableIf<Traits::IsSpecializationOf<Type, std::pair>> *>
837void pull(Type &reflectable,
const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors)
839 if (!value.IsArray()) {
841 errors->reportTypeMismatch<Type>(value.GetType());
845 const auto array = value.GetArray();
846 if (array.Size() != 2) {
849 errors->reportArraySizeMismatch();
853 pull(reflectable.first, array[0], errors);
854 pull(reflectable.second, array[1], errors);
860template <
typename Type, Traits::EnableIf<Traits::IsSpecializationOf<Type, std::unique_ptr>> *>
861void pull(Type &reflectable,
const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors)
863 if (value.IsNull()) {
867 reflectable = std::make_unique<typename Type::element_type>();
868 pull(*reflectable, value, errors);
874template <
typename Type, Traits::EnableIf<Traits::IsSpecializationOf<Type, std::shared_ptr>> *>
875void pull(Type &reflectable,
const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors)
877 if (value.IsNull()) {
881 reflectable = std::make_shared<typename Type::element_type>();
882 pull(*reflectable, value, errors);
888template <
typename Type, Traits::EnableIf<Traits::IsSpecializationOf<Type, std::optional>> *>
889void pull(Type &reflectable,
const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors)
891 if (value.IsNull()) {
894 pull(reflectable.emplace(), value, errors);
900template <
typename Variant, std::
size_t compiletimeIndex = 0>
901void assignVariantValueByRuntimeIndex(std::size_t runtimeIndex, Variant &variant,
902 const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors)
904 if constexpr (compiletimeIndex < std::variant_size_v<Variant>) {
905 if (compiletimeIndex == runtimeIndex) {
906 if constexpr (std::is_same_v<std::variant_alternative_t<compiletimeIndex, Variant>, std::monostate>) {
907 variant = std::monostate{};
909 pull(variant.template emplace<compiletimeIndex>(), value, errors);
912 assignVariantValueByRuntimeIndex<Variant, compiletimeIndex + 1>(runtimeIndex, variant, value, errors);
917 errors->currentMember, errors->currentIndex);
927template <
typename Type, Traits::EnableIf<IsVariant<Type>> *>
928void pull(Type &reflectable,
const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors)
930 if (!value.IsObject()) {
932 errors->reportTypeMismatch<Type>(value.GetType());
937 auto obj = value.GetObject();
938 auto indexIterator = obj.FindMember(
"index");
939 auto dataIterator = obj.FindMember(
"data");
940 if (indexIterator == obj.MemberEnd() || dataIterator == obj.MemberEnd()) {
943 errors->currentMember, errors->currentIndex);
947 const auto &indexValue = indexIterator->value;
948 if (!indexValue.IsUint64()) {
951 errors->currentRecord, errors->currentMember, errors->currentIndex);
955 Detail::assignVariantValueByRuntimeIndex(indexValue.GetUint64(), reflectable, dataIterator->value, errors);
961template <
typename Type>
962inline void pull(Type &reflectable, rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>>::ValueIterator &value,
JsonDeserializationErrors *errors)
973template <
typename Type>
974inline void pull(Type &reflectable,
const char *name,
const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>>::ConstObject &value,
978 const auto member = value.FindMember(name);
979 if (member == value.MemberEnd()) {
984 const char *previousMember =
nullptr;
991 pull<Type>(reflectable, member->value, errors);
1002template <
typename Type, Traits::DisableIf<IsBuiltInType<Type>> *>
1003void pull(Type &reflectable,
const RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value,
JsonDeserializationErrors *errors)
1005 if (!value.IsObject()) {
1011 pull(reflectable, value.GetObject(), errors);
1019template <
typename Type, Traits::EnableIfAny<IsJsonSerializable<Type>, IsMapOrHash<Type>, IsMultiMapOrHash<Type>> * =
nullptr>
1020RAPIDJSON_NAMESPACE::Document
toJsonDocument(
const Type &reflectable)
1022 RAPIDJSON_NAMESPACE::Document document(RAPIDJSON_NAMESPACE::kObjectType);
1023 push(reflectable, document, document.GetAllocator());
1030template <
typename Type, Traits::EnableIfAny<std::is_
integral<Type>, std::is_
floating_po
int<Type>> * =
nullptr>
1033 RAPIDJSON_NAMESPACE::Document document(RAPIDJSON_NAMESPACE::kNumberType);
1034 document.Set(reflectable, document.GetAllocator());
1041template <
typename Type, Traits::EnableIf<std::is_same<Type, std::
string>> * =
nullptr>
1042RAPIDJSON_NAMESPACE::Document
toJsonDocument(
const std::string &reflectable)
1044 RAPIDJSON_NAMESPACE::Document document(RAPIDJSON_NAMESPACE::kStringType);
1045 document.SetString(RAPIDJSON_NAMESPACE::StringRef(reflectable.data(), reflectable.size()), document.GetAllocator());
1052template <
typename Type, Traits::EnableIf<std::is_same<Type, const
char *>> * =
nullptr>
1053RAPIDJSON_NAMESPACE::Document
toJsonDocument(
const char *reflectable)
1055 RAPIDJSON_NAMESPACE::Document document(RAPIDJSON_NAMESPACE::kStringType);
1056 document.SetString(RAPIDJSON_NAMESPACE::StringRef(reflectable), document.GetAllocator());
1063template <
typename Type, Traits::EnableIf<std::is_same<Type, std::
string_view>> * =
nullptr>
1064RAPIDJSON_NAMESPACE::Document
toJsonDocument(std::string_view reflectable)
1066 RAPIDJSON_NAMESPACE::Document document(RAPIDJSON_NAMESPACE::kStringType);
1067 document.SetString(RAPIDJSON_NAMESPACE::StringRef(reflectable.data(), reflectable.size()), document.GetAllocator());
1074template <
typename Type, Traits::EnableIf<IsArray<Type>> * =
nullptr> RAPIDJSON_NAMESPACE::Document
toJsonDocument(
const Type &reflectable)
1076 RAPIDJSON_NAMESPACE::Document document(RAPIDJSON_NAMESPACE::kArrayType);
1077 push(reflectable, document, document.GetAllocator());
1084template <
typename Type,
1087RAPIDJSON_NAMESPACE::StringBuffer
toJson(
const Type &reflectable)
1098template <
typename Type, Traits::EnableIfAny<IsJsonSerializable<Type>, IsMapOrHash<Type>, IsMultiMapOrHash<Type>> * =
nullptr>
1102 if (!doc.IsObject()) {
1117template <
typename Type, Traits::EnableIfAny<std::is_
integral<Type>, std::is_
floating_po
int<Type>> * =
nullptr>
1121 if (!doc.Is<Type>()) {
1128 return doc.Get<Type>();
1134template <
typename Type, Traits::EnableIf<std::is_same<Type, std::
string>> * =
nullptr>
1135Type
fromJson(
const char *json, std::size_t jsonSize, JsonDeserializationErrors *errors =
nullptr)
1138 if (!doc.IsString()) {
1145 return doc.GetString();
1151template <
typename Type, Traits::EnableIf<IsArray<Type>> * =
nullptr>
1152Type
fromJson(
const char *json, std::size_t jsonSize, JsonDeserializationErrors *errors =
nullptr)
1155 if (!doc.IsArray()) {
1170template <
typename Type> Type
fromJson(
const char *json, JsonDeserializationErrors *errors =
nullptr)
1178template <
typename Type> Type
fromJson(
const std::string &json, JsonDeserializationErrors *errors =
nullptr)