Reflection for RapidJSON  0.0.6
Reflection for serializing/deserializing with RapidJSON
errorhandling.h
Go to the documentation of this file.
1 #ifndef REFLECTIVE_RAPIDJSON_JSON_ERROR_HANDLING_H
2 #define REFLECTIVE_RAPIDJSON_JSON_ERROR_HANDLING_H
3 
9 #include <c++utilities/conversion/types.h>
10 #include <c++utilities/misc/traits.h>
11 
12 #include <rapidjson/rapidjson.h>
13 
14 #include <limits>
15 #include <list>
16 #include <string>
17 #include <vector>
18 
19 namespace ReflectiveRapidJSON {
20 
24 enum class JsonDeserializationErrorKind : byte {
25  TypeMismatch,
29 };
30 
35 enum class JsonType : byte {
36  Null,
37  Number,
38  Bool,
39  String,
40  Array,
41  Object,
42 };
43 
44 // define helper functions which return the JsonType for the C++ type specified as template parameter
45 
46 template <typename Type,
47  Traits::EnableIf<Traits::Not<std::is_same<Type, bool>>, Traits::Any<std::is_integral<Type>, std::is_floating_point<Type>>> * = nullptr>
48 constexpr JsonType jsonType()
49 {
50  return JsonType::Number;
51 }
52 
53 template <typename Type, Traits::EnableIfAny<std::is_same<Type, bool>> * = nullptr> constexpr JsonType jsonType()
54 {
55  return JsonType::Bool;
56 }
57 
58 template <typename Type, Traits::EnableIfAny<Traits::IsString<Type>, Traits::IsCString<Type>> * = nullptr> constexpr JsonType jsonType()
59 {
60  return JsonType::String;
61 }
62 
63 template <typename Type,
64  Traits::EnableIf<Traits::IsIteratable<Type>,
65  Traits::Not<Traits::Any<Traits::IsString<Type>, Traits::IsSpecializationOf<Type, std::map>,
66  Traits::IsSpecializationOf<Type, std::unordered_map>>>> * = nullptr>
67 constexpr JsonType jsonType()
68 {
69  return JsonType::Array;
70 }
71 
72 template <typename Type,
73  Traits::DisableIfAny<std::is_integral<Type>, std::is_floating_point<Type>, Traits::IsString<Type>, Traits::IsCString<Type>,
74  Traits::All<Traits::IsIteratable<Type>,
75  Traits::Not<Traits::Any<Traits::IsString<Type>, Traits::IsSpecializationOf<Type, std::map>,
76  Traits::IsSpecializationOf<Type, std::unordered_map>>>>> * = nullptr>
77 constexpr JsonType jsonType()
78 {
79  return JsonType::Object;
80 }
81 
85 constexpr JsonType jsonType(RAPIDJSON_NAMESPACE::Type type)
86 {
87  switch (type) {
88  case RAPIDJSON_NAMESPACE::kFalseType:
89  case RAPIDJSON_NAMESPACE::kTrueType:
90  return JsonType::Bool;
91  case RAPIDJSON_NAMESPACE::kObjectType:
92  return JsonType::Object;
93  case RAPIDJSON_NAMESPACE::kArrayType:
94  return JsonType::Array;
95  case RAPIDJSON_NAMESPACE::kStringType:
96  return JsonType::String;
97  case RAPIDJSON_NAMESPACE::kNumberType:
98  return JsonType::Number;
99  default:
100  return JsonType::Null;
101  }
102 }
103 
109  const char *member = nullptr, std::size_t index = noIndex);
110 
118  const char *record;
120  const char *member;
122  std::size_t index;
123 
125  static constexpr std::size_t noIndex = std::numeric_limits<std::size_t>::max();
126 };
127 
133  JsonDeserializationErrorKind kind, JsonType expectedType, JsonType actualType, const char *record, const char *member, std::size_t index)
134  : kind(kind)
135  , expectedType(expectedType)
136  , actualType(actualType)
137  , record(record)
138  , member(member)
139  , index(index)
140 {
141 }
142 
152 struct JsonDeserializationErrors : public std::vector<JsonDeserializationError> {
154 
155  template <typename ExpectedType> void reportTypeMismatch(RAPIDJSON_NAMESPACE::Type presentType);
159 
161  const char *currentRecord;
163  const char *currentMember;
165  std::size_t currentIndex;
167  enum class ThrowOn : byte { None = 0, TypeMismatch = 0x1, ArraySizeMismatch = 0x2, ConversionError = 0x4, UnexpectedDuplicate = 0x8 } throwOn;
168 
169 private:
170  void throwMaybe(ThrowOn on) const;
171 };
172 
177  : currentRecord("[document]")
178  , currentMember(nullptr)
179  , currentIndex(JsonDeserializationError::noIndex)
180  , throwOn(ThrowOn::None)
181 {
182 }
183 
188 {
189  return static_cast<JsonDeserializationErrors::ThrowOn>(static_cast<byte>(lhs) | static_cast<byte>(rhs));
190 }
191 
197 inline void JsonDeserializationErrors::throwMaybe(ThrowOn on) const
198 {
199  if (static_cast<byte>(throwOn) & static_cast<byte>(on)) {
200  throw back();
201  }
202 }
203 
207 template <typename ExpectedType> inline void JsonDeserializationErrors::reportTypeMismatch(RAPIDJSON_NAMESPACE::Type presentType)
208 {
209  emplace_back(
211  throwMaybe(ThrowOn::TypeMismatch);
212 }
213 
220 {
222  throwMaybe(ThrowOn::ArraySizeMismatch);
223 }
224 
231 {
233  throwMaybe(ThrowOn::ConversionError);
234 }
235 
242 {
244  throwMaybe(ThrowOn::UnexpectedDuplicate);
245 }
246 
247 } // namespace ReflectiveRapidJSON
248 
249 #endif // REFLECTIVE_RAPIDJSON_JSON_REFLECTOR_H
ThrowOn
The list of fatal error types in form of flags.
JsonDeserializationErrorKind
The JsonDeserializationErrorKind enum specifies which kind of error happend when populating variables...
Definition: errorhandling.h:24
const char * currentMember
The name of the member (in currentRecord) which is currently being processed.
constexpr JsonType jsonType()
Definition: errorhandling.h:48
const char * record
The name of the class or struct which was being processed when the error was ascertained.
JsonType
The JsonType enum specifies the JSON data type.
Definition: errorhandling.h:35
void reportConversionError(JsonType jsonType)
Reports a conversion error.
JsonType actualType
The actual type (might not be relevant for all error kinds).
std::size_t currentIndex
The index in the array which is currently processed.
enum ReflectiveRapidJSON::JsonDeserializationErrors::ThrowOn throwOn
JsonDeserializationErrorKind kind
Which kind of error occured.
void reportTypeMismatch(RAPIDJSON_NAMESPACE::Type presentType)
Reports a type mismatch between.
The JsonDeserializationErrors struct can be passed to fromJson() for error handling.
JsonDeserializationErrors()
Creates an empty JsonDeserializationErrors object with default context and no errors considered fatal...
JsonType expectedType
The expected type (might not be relevant for all error kinds).
static constexpr std::size_t noIndex
Indicates no array was being processed when the error occured.
void reportArraySizeMismatch()
Reports an array size mismatch.
const char * currentRecord
The name of the class or struct which is currently being processed.
The JsonDeserializationError struct describes any errors of fromJson() except such caused by invalid ...
JsonDeserializationError(JsonDeserializationErrorKind kind, JsonType expectedType, JsonType actualType, const char *record, const char *member=nullptr, std::size_t index=noIndex)
Constructs a new JsonDeserializationError.
void reportUnexpectedDuplicate(JsonType jsonType)
Reports an unexpected duplicate.
const char * member
The name of the member which was being processed when the error was ascertained.
std::size_t index
The index in the array which was being processed when the error was ascertained.
constexpr JsonDeserializationErrors::ThrowOn operator|(JsonDeserializationErrors::ThrowOn lhs, JsonDeserializationErrors::ThrowOn rhs)
Combines to ThrowOn values.