Reflection for RapidJSON  0.0.2
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,
28 };
29 
34 enum class JsonType : byte {
35  Null,
36  Number,
37  Bool,
38  String,
39  Array,
40  Object,
41 };
42 
43 // define helper functions which return the JsonType for the C++ type specified as template parameter
44 
45 template <typename Type,
46  Traits::EnableIf<Traits::Not<std::is_same<Type, bool>>, Traits::Any<std::is_integral<Type>, std::is_floating_point<Type>>>...>
47 constexpr JsonType jsonType()
48 {
49  return JsonType::Number;
50 }
51 
52 template <typename Type, Traits::EnableIfAny<std::is_same<Type, bool>>...> constexpr JsonType jsonType()
53 {
54  return JsonType::Bool;
55 }
56 
57 template <typename Type, Traits::EnableIfAny<Traits::IsString<Type>, Traits::IsCString<Type>>...> constexpr JsonType jsonType()
58 {
59  return JsonType::String;
60 }
61 
62 template <typename Type,
63  Traits::EnableIf<Traits::IsIteratable<Type>,
64  Traits::Not<Traits::Any<Traits::IsString<Type>, Traits::IsSpecializationOf<Type, std::map>,
65  Traits::IsSpecializationOf<Type, std::unordered_map>>>>...>
66 constexpr JsonType jsonType()
67 {
68  return JsonType::Array;
69 }
70 
71 template <typename Type,
72  Traits::DisableIfAny<std::is_integral<Type>, std::is_floating_point<Type>, Traits::IsString<Type>, Traits::IsCString<Type>,
73  Traits::All<Traits::IsIteratable<Type>,
74  Traits::Not<Traits::Any<Traits::IsString<Type>, Traits::IsSpecializationOf<Type, std::map>,
75  Traits::IsSpecializationOf<Type, std::unordered_map>>>>>...>
76 constexpr JsonType jsonType()
77 {
78  return JsonType::Object;
79 }
80 
84 constexpr JsonType jsonType(RAPIDJSON_NAMESPACE::Type type)
85 {
86  switch (type) {
87  case RAPIDJSON_NAMESPACE::kFalseType:
88  case RAPIDJSON_NAMESPACE::kTrueType:
89  return JsonType::Bool;
90  case RAPIDJSON_NAMESPACE::kObjectType:
91  return JsonType::Object;
92  case RAPIDJSON_NAMESPACE::kArrayType:
93  return JsonType::Array;
94  case RAPIDJSON_NAMESPACE::kStringType:
95  return JsonType::String;
96  case RAPIDJSON_NAMESPACE::kNumberType:
97  return JsonType::Number;
98  default:
99  return JsonType::Null;
100  }
101 }
102 
108  const char *member = nullptr, std::size_t index = noIndex);
109 
117  const char *record;
119  const char *member;
121  std::size_t index;
122 
124  static constexpr std::size_t noIndex = std::numeric_limits<std::size_t>::max();
125 };
126 
132  JsonDeserializationErrorKind kind, JsonType expectedType, JsonType actualType, const char *record, const char *member, std::size_t index)
133  : kind(kind)
134  , expectedType(expectedType)
135  , actualType(actualType)
136  , record(record)
137  , member(member)
138  , index(index)
139 {
140 }
141 
151 struct JsonDeserializationErrors : public std::vector<JsonDeserializationError> {
153 
154  template <typename ExpectedType> void reportTypeMismatch(RAPIDJSON_NAMESPACE::Type presentType);
157 
159  const char *currentRecord;
161  const char *currentMember;
163  std::size_t currentIndex;
165  enum class ThrowOn : byte { None = 0, TypeMismatch = 0x1, ArraySizeMismatch = 0x2, ConversionError = 0x4 } throwOn;
166 
167 private:
168  void throwMaybe(ThrowOn on) const;
169 };
170 
175  : currentRecord("[document]")
176  , currentMember(nullptr)
177  , currentIndex(JsonDeserializationError::noIndex)
178  , throwOn(ThrowOn::None)
179 {
180 }
181 
186 {
187  return static_cast<JsonDeserializationErrors::ThrowOn>(static_cast<byte>(lhs) | static_cast<byte>(rhs));
188 }
189 
195 inline void JsonDeserializationErrors::throwMaybe(ThrowOn on) const
196 {
197  if (static_cast<byte>(throwOn) & static_cast<byte>(on)) {
198  throw back();
199  }
200 }
201 
205 template <typename ExpectedType> inline void JsonDeserializationErrors::reportTypeMismatch(RAPIDJSON_NAMESPACE::Type presentType)
206 {
207  emplace_back(
209  throwMaybe(ThrowOn::TypeMismatch);
210 }
211 
218 {
220  throwMaybe(ThrowOn::ArraySizeMismatch);
221 }
222 
229 {
231  throwMaybe(ThrowOn::ConversionError);
232 }
233 
234 } // namespace ReflectiveRapidJSON
235 
236 #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:47
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:34
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.
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.