8 #include <nlohmann/json.hpp>
14 namespace nl = nlohmann;
19 #define OBJECT_SERIALIZE_FIELD(json, json_field, field) \
20 json[json_field] = field;
22 #define OBJECT_SERIALIZE_FIELD_PTR(json, json_field, field) \
24 json[json_field] = field->toJson(); \
27 #define OBJECT_SERIALIZE_FIELD_PTR_ARRAY(json, json_field, array_field) \
28 json[json_field] = nl::json::array(); \
29 for (const auto& e: array_field) \
30 json[json_field].push_back(e->toJson());
32 #define OBJECT_SERIALIZE_FIELD_PTR_ARRAY_ARRAY(json, json_field, array_array_field) \
33 json[json_field] = nl::json::array(); \
34 for (const auto& array: array_array_field) { \
35 nl::json arr = nl::json::array(); \
36 for (const auto& e: array) { \
37 arr.push_back(e->toJson()); \
39 json[json_field].push_back(arr); \
44 #define OBJECT_DESERIALIZE_FIELD(json, json_field, field, default_value, optional) \
45 if (json.contains(json_field)) { \
47 using T = std::remove_reference_t<std::remove_const_t<decltype(field)>>; \
48 field = json[json_field].get<T>(); \
49 } catch (const std::exception& e) { \
50 std::ostringstream err{}; \
51 err << __FILE__ << ':' << __LINE__ << ": " << __FUNCTION__ << ": Failed to deserialize \"" \
52 << json_field << "\" from json object: " << json.dump(2) << "\nReason: " << e.what(); \
53 throw Exception(err.str()); \
55 std::ostringstream err{}; \
56 err << __FILE__ << ':' << __LINE__ << ": " << __FUNCTION__ << ": Failed to deserialize \"" \
57 << json_field << "\" from json object: " << json.dump(2); \
58 throw Exception(err.str()); \
61 if (not(optional)) { \
62 std::ostringstream err{}; \
63 err << __FILE__ << ':' << __LINE__ << ": " << __FUNCTION__ << ": Missing required field \"" \
64 << json_field << "\" from json object: " << json.dump(2); \
65 throw Exception(err.str()); \
67 field = default_value; \
70 #define OBJECT_DESERIALIZE_FIELD_PTR(json, json_field, field, optional) \
71 static_assert(!std::is_const_v<decltype(field)>, "OBJECT_DESERIALIZE_FIELD_PTR: 'field' must not be const"); \
72 static_assert(std::is_same_v<decltype(optional), bool>, "OBJECT_DESERIALIZE_FIELD_PTR: 'optional' must be boolean"); \
73 if (json.contains(json_field) and json[json_field].is_object() and not json[json_field].empty()) { \
74 using T = std::remove_reference_t<decltype(field)>; \
75 using E = T::element_type; \
76 field.reset(new (E)(json[json_field])); \
78 if (not(optional)) { \
79 std::ostringstream err{}; \
80 err << __FILE__ << ':' << __LINE__ << ": " << __FUNCTION__ << ": Missing required field \"" \
81 << json_field << "\" from json object: " << json.dump(2); \
82 throw Exception(err.str()); \
87 #define OBJECT_DESERIALIZE_FIELD_PTR_ARRAY(json, json_field, array_field, optional) \
88 static_assert(!std::is_const_v<decltype(array_field)>, "OBJECT_DESERIALIZE_FIELD_PTR_ARRAY: 'field' must not be const"); \
89 static_assert(std::is_same_v<decltype(optional), bool>, "OBJECT_DESERIALIZE_FIELD_PTR_ARRAY: 'optional' must be boolean"); \
90 if ((json.contains(json_field)) and (json[json_field].is_array())) { \
91 using T = std::remove_reference_t<std::remove_const_t<decltype(array_field)::value_type>>; \
92 using E = T::element_type; \
93 array_field.reserve(json[json_field].size()); \
94 for (const nl::json& obj: json[json_field]) { \
95 array_field.emplace_back(new E(obj)); \
98 if (not(optional)) { \
99 std::ostringstream err{}; \
100 err << __FILE__ << ':' << __LINE__ << ": " << __FUNCTION__ << ": Missing required field \"" \
101 << json_field << "\" from json object: " << json.dump(2); \
102 throw Exception(err.str()); \
104 array_field.clear(); \
108 #define OBJECT_DESERIALIZE_FIELD_PTR_ARRAY_ARRAY(json, json_field, array_array_field, optional) \
109 static_assert(!std::is_const_v<decltype(array_array_field)>, "OBJECT_DESERIALIZE_FIELD_PTR_ARRAY_ARRAY: 'field' must not be const"); \
110 static_assert(std::is_same_v<decltype(optional), bool>, "OBJECT_DESERIALIZE_FIELD_PTR_ARRAY_ARRAY: 'optional' must be boolean"); \
111 if ((json.contains(json_field)) and (json[json_field].is_array())) { \
112 using ArrayArray = decltype(array_array_field); \
113 using Array = ArrayArray::value_type;
\
114 using T = ArrayArray::value_type::value_type; \
115 using E = T::element_type; \
116 array_array_field.reserve(json[json_field].size()); \
117 for (const nl::json& array: json[json_field]) { \
119 arr.reserve(array.size()); \
120 for (const nl::json& obj: array) { \
121 arr.emplace_back(new E(obj)); \
123 array_array_field.push_back(std::move(arr)); \
126 if (not(optional)) { \
127 std::ostringstream err{}; \
128 err << __FILE__ << ':' << __LINE__ << ": " << __FUNCTION__ << ": Missing required field \"" \
129 << json_field << "\" from json object: " << json.dump(2); \
130 throw Exception(err.str()); \
132 array_array_field.clear(); \