1 #ifndef REFLECTIVE_RAPIDJSON_JSON_REFLECTOR_H 2 #define REFLECTIVE_RAPIDJSON_JSON_REFLECTOR_H 10 #include "../traits.h" 12 #include <c++utilities/conversion/types.h> 14 #include <rapidjson/document.h> 15 #include <rapidjson/rapidjson.h> 16 #include <rapidjson/stringbuffer.h> 17 #include <rapidjson/writer.h> 34 static constexpr
const char *
name =
"AdaptedJsonSerializable";
35 static constexpr
const char *
qualifiedName =
"ReflectiveRapidJSON::AdaptedJsonSerializable";
41 namespace JsonReflector {
48 return size > std::numeric_limits<RAPIDJSON_NAMESPACE::SizeType>::max() ? std::numeric_limits<RAPIDJSON_NAMESPACE::SizeType>::max()
49 : static_cast<RAPIDJSON_NAMESPACE::SizeType>(size);
57 RAPIDJSON_NAMESPACE::StringBuffer buffer;
58 RAPIDJSON_NAMESPACE::Writer<RAPIDJSON_NAMESPACE::StringBuffer> writer(buffer);
59 document.Accept(writer);
68 RAPIDJSON_NAMESPACE::Document document(RAPIDJSON_NAMESPACE::kObjectType);
69 const RAPIDJSON_NAMESPACE::ParseResult parseRes = document.Parse(json, jsonSize);
70 if (parseRes.IsError()) {
77 template <
typename Type>
78 using IsBuiltInType = Traits::Any<std::is_integral<Type>, std::is_floating_point<Type>, std::is_pointer<Type>, std::is_enum<Type>,
79 Traits::IsSpecializationOf<Type, std::tuple>, Traits::IsIteratable<Type>, Traits::IsSpecializationOf<Type, std::unique_ptr>,
80 Traits::IsSpecializationOf<Type, std::shared_ptr>, Traits::IsSpecializationOf<Type, std::weak_ptr>>;
81 template <
typename Type>
using IsCustomType = Traits::Not<IsBuiltInType<Type>>;
85 template <
typename Type>
94 template <
typename Type, Traits::DisableIf<IsBuiltInType<Type>> * =
nullptr>
95 void push(
const Type &reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator);
100 template <
typename Type, Traits::DisableIf<IsJsonSerializable<Type>> * =
nullptr>
101 void push(
const Type &reflectable, RAPIDJSON_NAMESPACE::Value::Array &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator);
106 template <
typename Type, Traits::EnableIf<IsJsonSerializable<Type>> * =
nullptr>
107 void push(
const Type &reflectable, RAPIDJSON_NAMESPACE::Value::Array &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator);
112 template <
typename Type, Traits::EnableIf<IsJsonSerializable<Type>> * =
nullptr>
114 const Type &reflectable,
const char *name, RAPIDJSON_NAMESPACE::Value::Object &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator);
119 template <
typename Type, Traits::DisableIf<IsJsonSerializable<Type>> * =
nullptr>
121 const Type &reflectable,
const char *name, RAPIDJSON_NAMESPACE::Value::Object &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator);
127 template <
typename Type, Traits::DisableIf<IsBuiltInType<Type>> * =
nullptr>
128 void push(
const Type &reflectable, RAPIDJSON_NAMESPACE::Value::Object &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator);
133 template <
typename Type, Traits::DisableIf<IsBuiltInType<Type>> *>
134 inline void push(
const Type &reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
137 RAPIDJSON_NAMESPACE::Value::Object obj(value.GetObject());
138 push(reflectable, obj, allocator);
144 template <
typename Type, Traits::EnableIfAny<std::is_
integral<Type>, std::is_
floating_po
int<Type>> * =
nullptr>
145 inline void push(Type reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
147 value.Set(reflectable, allocator);
153 template <
typename Type, Traits::EnableIfAny<std::is_enum<Type>> * =
nullptr>
154 inline void push(Type reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
156 value.Set(
static_cast<Traits::Conditional<std::is_unsigned<typename std::underlying_type<Type>::type
>, uint64, int64>>(reflectable), allocator);
162 template <
typename Type, Traits::EnableIf<std::is_same<Type, const
char *>> * =
nullptr>
163 inline void push(Type reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
165 value.SetString(RAPIDJSON_NAMESPACE::StringRef(reflectable), allocator);
171 template <
typename Type, Traits::EnableIf<std::is_same<Type, const
char *const &>> * =
nullptr>
172 inline void push(
const char *
const &reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
174 value.SetString(RAPIDJSON_NAMESPACE::StringRef(reflectable), allocator);
180 template <
typename Type, Traits::EnableIf<std::is_same<Type, std::
string>> * =
nullptr>
181 inline void push(
const Type &reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
183 value.SetString(RAPIDJSON_NAMESPACE::StringRef(reflectable.data(), reflectable.size()), allocator);
189 template <
typename Type, Traits::EnableIf<IsArrayOrSet<Type>, Traits::HasSize<Type>> * =
nullptr>
190 void push(
const Type &reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
193 RAPIDJSON_NAMESPACE::Value::Array array(value.GetArray());
194 array.Reserve(reflectable.size(), allocator);
195 for (
const auto &item : reflectable) {
196 push(item, array, allocator);
203 template <
typename Type, Traits::EnableIf<IsArrayOrSet<Type>, Traits::Not<Traits::HasSize<Type>>> * =
nullptr>
204 void push(
const Type &reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
207 RAPIDJSON_NAMESPACE::Value::Array array(value.GetArray());
208 for (
const auto &item : reflectable) {
209 push(item, array, allocator);
217 template <
typename Type, Traits::EnableIfAny<IsMapOrHash<Type>, IsMultiMapOrHash<Type>> * =
nullptr>
218 void push(
const Type &reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
221 RAPIDJSON_NAMESPACE::Value::Object object(value.GetObject());
222 for (
const auto &item : reflectable) {
223 push(item.second, item.first.data(), object, allocator);
233 static void push(
const Tuple &tuple, RAPIDJSON_NAMESPACE::Value::Array &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
241 static void push(
const Tuple &tuple, RAPIDJSON_NAMESPACE::Value::Array &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
251 template <
typename Type, Traits::EnableIf<Traits::IsSpecializationOf<Type, std::tuple>> * =
nullptr>
252 void push(
const Type &reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
255 RAPIDJSON_NAMESPACE::Value::Array array(value.GetArray());
256 array.Reserve(std::tuple_size<Type>::value, allocator);
257 Detail::TuplePushHelper<Type, std::tuple_size<Type>::value>
::push(reflectable, array, allocator);
263 template <
typename Type,
264 Traits::EnableIfAny<Traits::IsSpecializationOf<Type, std::unique_ptr>, Traits::IsSpecializationOf<Type, std::shared_ptr>,
265 Traits::IsSpecializationOf<Type, std::weak_ptr>> * =
nullptr>
266 void push(
const Type &reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
272 push(*reflectable, value, allocator);
278 template <
typename Type, Traits::EnableIf<IsJsonSerializable<Type>> *>
279 void push(
const Type &reflectable, RAPIDJSON_NAMESPACE::Value::Array &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
281 RAPIDJSON_NAMESPACE::Value objectValue(RAPIDJSON_NAMESPACE::kObjectType);
282 RAPIDJSON_NAMESPACE::Value::Object object(objectValue.GetObject());
283 push(reflectable,
object, allocator);
284 value.PushBack(objectValue, allocator);
290 template <
typename Type, Traits::DisableIf<IsJsonSerializable<Type>> *>
291 void push(
const Type &reflectable, RAPIDJSON_NAMESPACE::Value::Array &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
293 RAPIDJSON_NAMESPACE::Value genericValue;
294 push(reflectable, genericValue, allocator);
295 value.PushBack(genericValue, allocator);
301 template <
typename Type, Traits::EnableIf<IsJsonSerializable<Type>> *>
303 const Type &reflectable,
const char *name, RAPIDJSON_NAMESPACE::Value::Object &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
305 RAPIDJSON_NAMESPACE::Value objectValue(RAPIDJSON_NAMESPACE::kObjectType);
306 RAPIDJSON_NAMESPACE::Value::Object object(objectValue.GetObject());
307 push(reflectable,
object, allocator);
308 value.AddMember(RAPIDJSON_NAMESPACE::StringRef(name), objectValue, allocator);
314 template <
typename Type, Traits::DisableIf<IsJsonSerializable<Type>> *>
316 const Type &reflectable,
const char *name, RAPIDJSON_NAMESPACE::Value::Object &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
318 RAPIDJSON_NAMESPACE::Value genericValue;
319 push(reflectable, genericValue, allocator);
320 value.AddMember(RAPIDJSON_NAMESPACE::StringRef(name), genericValue, allocator);
329 template <
typename Type, Traits::DisableIf<IsBuiltInType<Type>> * =
nullptr>
330 void pull(Type &reflectable,
const RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>>::ConstObject &value,
331 JsonDeserializationErrors *errors);
336 template <
typename Type, Traits::DisableIf<IsBuiltInType<Type>> * =
nullptr>
337 void pull(Type &reflectable,
const RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors);
342 template <
typename Type, Traits::EnableIf<IsArrayOrSet<Type>, Traits::Not<Traits::IsReservable<Type>>> * =
nullptr>
343 void pull(Type &reflectable,
const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors);
348 template <
typename Type, Traits::EnableIf<IsArrayOrSet<Type>, Traits::IsReservable<Type>> * =
nullptr>
349 void pull(Type &reflectable,
const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors);
354 template <
typename Type, Traits::EnableIf<IsArray<Type>> * =
nullptr>
355 void pull(Type &reflectable, rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>>::ConstArray array, JsonDeserializationErrors *errors);
360 template <
typename Type, Traits::EnableIf<IsSet<Type>> * =
nullptr>
361 void pull(Type &reflectable, rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>>::ConstArray array, JsonDeserializationErrors *errors);
366 template <
typename Type, Traits::EnableIf<IsMultiSet<Type>> * =
nullptr>
367 void pull(Type &reflectable, rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>>::ConstArray array, JsonDeserializationErrors *errors);
372 template <
typename Type, Traits::EnableIf<IsMapOrHash<Type>> * =
nullptr>
373 void pull(Type &reflectable,
const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors);
378 template <
typename Type, Traits::EnableIf<IsMultiMapOrHash<Type>> * =
nullptr>
379 void pull(Type &reflectable,
const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors);
384 template <
typename Type, Traits::EnableIf<Traits::IsSpecializationOf<Type, std::tuple>> * =
nullptr>
385 void pull(Type &reflectable,
const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors);
390 template <
typename Type, Traits::EnableIf<Traits::IsSpecializationOf<Type, std::unique_ptr>> * =
nullptr>
391 void pull(Type &reflectable,
const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors);
396 template <
typename Type, Traits::EnableIf<Traits::IsSpecializationOf<Type, std::shared_ptr>> * =
nullptr>
397 void pull(Type &reflectable,
const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors);
402 template <
typename Type>
404 Type &reflectable, rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>>::ValueIterator &value, JsonDeserializationErrors *errors);
411 template <
typename Type>
412 inline void pull(Type &reflectable,
const char *name,
const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>>::ConstObject &value,
413 JsonDeserializationErrors *errors);
418 template <
typename Type, Traits::DisableIf<IsBuiltInType<Type>> *>
419 void pull(Type &reflectable,
const RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors);
424 template <
typename Type,
425 Traits::EnableIf<Traits::Not<std::is_same<Type, bool>>, Traits::Any<std::is_integral<Type>, std::is_floating_point<Type>>> * =
nullptr>
427 Type &reflectable,
const RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value,
JsonDeserializationErrors *errors)
429 if (!value.IsNumber()) {
435 reflectable = value.Is<Type>() ? value.Get<Type>() : static_cast<Type>(value.GetDouble());
441 template <
typename Type, Traits::EnableIf<std::is_same<Type,
bool>> * =
nullptr>
443 Type &reflectable,
const RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value,
JsonDeserializationErrors *errors)
445 if (!value.IsBool()) {
451 reflectable = value.GetBool();
458 template <
typename Type, Traits::EnableIfAny<std::is_enum<Type>> * =
nullptr>
460 Type &reflectable,
const RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors)
462 using ExpectedType = Traits::Conditional<std::is_unsigned<typename std::underlying_type<Type>::type>, uint64, int64>;
463 if (!value.Is<ExpectedType>()) {
465 errors->reportTypeMismatch<ExpectedType>(value.GetType());
469 reflectable = static_cast<Type>(value.Get<ExpectedType>());
475 template <
typename Type, Traits::EnableIf<std::is_same<Type, std::
string>> * =
nullptr>
477 Type &reflectable,
const RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors)
479 if (!value.IsString()) {
481 errors->reportTypeMismatch<std::string>(value.GetType());
485 reflectable = value.GetString();
492 template <
typename Type, Traits::EnableIfAny<std::is_same<Type, const
char *>, std::is_same<Type, const
char *const &>> * =
nullptr>
493 inline void pull(Type &,
const RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors)
495 if (!value.IsString()) {
497 errors->reportTypeMismatch<std::string>(value.GetType());
506 template <
typename Type, Traits::EnableIf<IsArrayOrSet<Type>, Traits::Not<Traits::IsReservable<Type>>> *>
509 if (!value.IsArray()) {
515 pull(reflectable, value.GetArray(), errors);
521 template <
typename Type, Traits::EnableIf<IsArrayOrSet<Type>, Traits::IsReservable<Type>> *>
524 if (!value.IsArray()) {
530 auto array = value.GetArray();
531 reflectable.reserve(array.Size());
532 pull(reflectable, array, errors);
538 template <
typename Type, Traits::EnableIf<IsArray<Type>> *>
545 std::size_t index = 0;
546 for (
const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &item : array) {
552 reflectable.emplace_back();
553 pull(reflectable.back(), item, errors);
565 template <
typename Type, Traits::EnableIf<IsMultiSet<Type>> *>
572 std::size_t index = 0;
573 for (
const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &item : array) {
579 typename Type::value_type itemObj;
580 pull(itemObj, item, errors);
581 reflectable.emplace(move(itemObj));
593 template <
typename Type, Traits::EnableIf<IsSet<Type>> *>
594 void pull(Type &reflectable, rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>>::ConstArray array, JsonDeserializationErrors *errors)
600 std::size_t index = 0;
601 for (
const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &item : array) {
604 errors->currentIndex = index;
607 typename Type::value_type itemObj;
608 pull(itemObj, item, errors);
609 if (!reflectable.emplace(move(itemObj)).second) {
623 template <
typename Type, Traits::EnableIf<IsMapOrHash<Type>> *>
624 void pull(Type &reflectable,
const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors)
626 if (!value.IsObject()) {
628 errors->reportTypeMismatch<Type>(value.GetType());
632 auto obj = value.GetObject();
633 for (
auto i = obj.MemberBegin(), end = obj.MemberEnd(); i != end; ++i) {
634 pull(reflectable[i->name.GetString()], i->value, errors);
641 template <
typename Type, Traits::EnableIf<IsMultiMapOrHash<Type>> *>
642 void pull(Type &reflectable,
const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors)
644 if (!value.IsObject()) {
646 errors->reportTypeMismatch<Type>(value.GetType());
650 auto obj = value.GetObject();
651 for (
auto i = obj.MemberBegin(), end = obj.MemberEnd(); i != end; ++i) {
652 auto insertedIterator = reflectable.insert(
typename Type::value_type(i->name.GetString(),
typename Type::mapped_type()));
653 pull(insertedIterator->second, i->value, errors);
667 JsonReflector::pull<
typename std::tuple_element<N - 1, Tuple>::type>(std::get<N - 1>(tuple), value[N - 1], errors);
674 JsonReflector::pull<typename std::tuple_element<0, Tuple>::type>(std::get<0>(tuple), value[0], errors);
682 template <
typename Type, Traits::EnableIf<Traits::IsSpecializationOf<Type, std::tuple>> *>
685 if (!value.IsArray()) {
691 auto array = value.GetArray();
692 if (array.Size() != std::tuple_size<Type>::value) {
699 Detail::TuplePullHelper<Type, std::tuple_size<Type>::value>
::pull(reflectable, array, errors);
705 template <
typename Type, Traits::EnableIf<Traits::IsSpecializationOf<Type, std::unique_ptr>> *>
706 void pull(Type &reflectable,
const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors)
708 if (value.IsNull()) {
712 reflectable = std::make_unique<typename Type::element_type>();
713 pull(*reflectable, value, errors);
719 template <
typename Type, Traits::EnableIf<Traits::IsSpecializationOf<Type, std::shared_ptr>> *>
720 void pull(Type &reflectable,
const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors)
722 if (value.IsNull()) {
726 reflectable = std::make_shared<typename Type::element_type>();
727 pull(*reflectable, value, errors);
733 template <
typename Type>
736 pull<Type>(reflectable, *value, errors);
745 template <
typename Type>
746 inline void pull(Type &reflectable,
const char *name,
const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>>::ConstObject &value,
750 const auto member = value.FindMember(name);
751 if (member == value.MemberEnd()) {
756 const char *previousMember;
763 pull<Type>(reflectable, member->value, errors);
774 template <
typename Type, Traits::DisableIf<IsBuiltInType<Type>> *>
775 void pull(Type &reflectable,
const RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value,
JsonDeserializationErrors *errors)
777 if (!value.IsObject()) {
783 pull(reflectable, value.GetObject(), errors);
791 template <
typename Type, Traits::EnableIfAny<IsJsonSerializable<Type>, IsMapOrHash<Type>, IsMultiMapOrHash<Type>> * =
nullptr>
794 RAPIDJSON_NAMESPACE::Document document(RAPIDJSON_NAMESPACE::kObjectType);
795 RAPIDJSON_NAMESPACE::Document::Object object(document.GetObject());
796 push(reflectable,
object, document.GetAllocator());
803 template <
typename Type, Traits::EnableIfAny<std::is_
integral<Type>, std::is_
floating_po
int<Type>> * =
nullptr>
806 RAPIDJSON_NAMESPACE::Document document(RAPIDJSON_NAMESPACE::kNumberType);
807 document.Set(reflectable, document.GetAllocator());
814 template <
typename Type, Traits::EnableIf<std::is_same<Type, std::
string>> * =
nullptr>
817 RAPIDJSON_NAMESPACE::Document document(RAPIDJSON_NAMESPACE::kStringType);
818 document.SetString(RAPIDJSON_NAMESPACE::StringRef(reflectable.data(), reflectable.size()), document.GetAllocator());
825 template <
typename Type, Traits::EnableIf<std::is_same<Type, const
char *>> * =
nullptr>
828 RAPIDJSON_NAMESPACE::Document document(RAPIDJSON_NAMESPACE::kStringType);
829 document.SetString(RAPIDJSON_NAMESPACE::StringRef(reflectable), document.GetAllocator());
836 template <
typename Type, Traits::EnableIf<IsArray<Type>> * =
nullptr> RAPIDJSON_NAMESPACE::Document
toJsonDocument(
const Type &reflectable)
838 RAPIDJSON_NAMESPACE::Document document(RAPIDJSON_NAMESPACE::kArrayType);
839 push(reflectable, document, document.GetAllocator());
846 template <
typename Type,
847 Traits::EnableIfAny<IsJsonSerializable<Type>, IsMapOrHash<Type>, IsMultiMapOrHash<Type>, std::is_integral<Type>, std::is_floating_point<Type>,
848 Traits::IsString<Type>, IsArray<Type>> * =
nullptr>
849 RAPIDJSON_NAMESPACE::StringBuffer
toJson(
const Type &reflectable)
860 template <
typename Type, Traits::EnableIfAny<IsJsonSerializable<Type>, IsMapOrHash<Type>, IsMultiMapOrHash<Type>> * =
nullptr>
864 if (!doc.IsObject()) {
872 pull<Type>(res, doc.GetObject(), errors);
879 template <
typename Type, Traits::EnableIfAny<std::is_
integral<Type>, std::is_
floating_po
int<Type>> * =
nullptr>
883 if (!doc.Is<Type>()) {
890 return doc.Get<Type>();
896 template <
typename Type, Traits::EnableIf<std::is_same<Type, std::
string>> * =
nullptr>
897 Type
fromJson(
const char *json, std::size_t jsonSize, JsonDeserializationErrors *errors =
nullptr)
900 if (!doc.IsString()) {
907 return doc.GetString();
913 template <
typename Type, Traits::EnableIf<IsArray<Type>> * =
nullptr>
914 Type
fromJson(
const char *json, std::size_t jsonSize, JsonDeserializationErrors *errors =
nullptr)
917 if (!doc.IsArray()) {
925 pull<Type>(res, doc.GetArray(), errors);
934 return fromJson<Type>(json, std::strlen(json), errors);
942 return fromJson<Type>(json.data(), json.size(), errors);
948 #endif // REFLECTIVE_RAPIDJSON_JSON_REFLECTOR_H Contains helper for error handling when deserializing JSON files.
RAPIDJSON_NAMESPACE::StringBuffer serializeJsonDocToString(RAPIDJSON_NAMESPACE::Document &document)
Serializes the specified JSON document.
static void pull(Tuple &tuple, const RAPIDJSON_NAMESPACE::Value::ConstArray value, JsonDeserializationErrors *errors)
static void push(const Tuple &tuple, RAPIDJSON_NAMESPACE::Value::Array &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
RAPIDJSON_NAMESPACE::Document parseJsonDocFromString(const char *json, std::size_t jsonSize)
Parses the specified JSON string.
The AdaptedJsonSerializable class allows considering 3rd party classes as serializable.
Traits::Any< Traits::Not< Traits::IsComplete< Type > >, std::is_base_of< JsonSerializable< Type >, Type >, AdaptedJsonSerializable< Type > > IsJsonSerializable
const char * currentMember
The name of the member (in currentRecord) which is currently being processed.
constexpr RAPIDJSON_NAMESPACE::SizeType rapidJsonSize(std::size_t size)
Casts the specified size to the size type used by RapidJSON ensuring no overflow happens.
static constexpr const char * qualifiedName
static void push(const Tuple &tuple, RAPIDJSON_NAMESPACE::Value::Array &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
RAPIDJSON_NAMESPACE::StringBuffer toJson(const Type &reflectable)
Serializes the specified reflectable.
static constexpr const char * name
std::size_t currentIndex
The index in the array which is currently processed.
Traits::Not< IsBuiltInType< Type > > IsCustomType
static void pull(Tuple &tuple, const RAPIDJSON_NAMESPACE::Value::ConstArray value, JsonDeserializationErrors *errors)
void reportTypeMismatch(RAPIDJSON_NAMESPACE::Type presentType)
Reports a type mismatch between.
The JsonDeserializationErrors struct can be passed to fromJson() for error handling.
The TuplePullHelper class helps deserializing tuples from JSON arrays.
The TuplePushHelper class helps serializing tuples to JSON arrays.
static constexpr std::size_t noIndex
Indicates no array was being processed when the error occured.
Type fromJson(const char *json, std::size_t jsonSize, JsonDeserializationErrors *errors=nullptr)
Deserializes the specified JSON to.
void reportArraySizeMismatch()
Reports an array size mismatch.
void pull(Type &reflectable, const RAPIDJSON_NAMESPACE::GenericValue< RAPIDJSON_NAMESPACE::UTF8< char >>::ConstObject &value, JsonDeserializationErrors *errors)
Pulls the reflectable which has a custom type from the specified object.
Traits::Any< std::is_integral< Type >, std::is_floating_point< Type >, std::is_pointer< Type >, std::is_enum< Type >, Traits::IsSpecializationOf< Type, std::tuple >, Traits::IsIteratable< Type >, Traits::IsSpecializationOf< Type, std::unique_ptr >, Traits::IsSpecializationOf< Type, std::shared_ptr >, Traits::IsSpecializationOf< Type, std::weak_ptr > > IsBuiltInType
void push(const Type &reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
Pushes the specified reflectable to the specified value.
The JsonSerializable class provides the CRTP-base for (de)serializable objects.
RAPIDJSON_NAMESPACE::Document toJsonDocument(const Type &reflectable)
Serializes the specified reflectable which has a custom type or can be mapped to and object.