tgbotxx 1.1.6.9
Telegram Bot C++ Library
Loading...
Searching...
No Matches
Object.hpp
Go to the documentation of this file.
1#pragma once
3#include <type_traits>
4#include <cstdint>
5#include <ctime>
6#include <iostream>
7#include <memory>
8#include <nlohmann/json.hpp>
9#include <sstream>
10#include <string>
11#include <tgbotxx/Exception.hpp>
12#include <tgbotxx/utils/Ptr.hpp>
13#include <vector>
14namespace nl = nlohmann;
15
17
19#define OBJECT_SERIALIZE_FIELD(json, json_field, field) \
20 json[json_field] = field;
21
22#define OBJECT_SERIALIZE_FIELD_PTR(json, json_field, field) \
23 if (field) { \
24 json[json_field] = field->toJson(); \
25 }
26
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());
31
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()); \
38 } \
39 json[json_field].push_back(arr); \
40 }
41
42
44#define OBJECT_DESERIALIZE_FIELD(json, json_field, field, default_value, optional) \
45 if (json.contains(json_field)) { \
46 try { \
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()); \
54 } catch (...) { \
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()); \
59 } \
60 } else { \
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()); \
66 } \
67 field = default_value; \
68 }
69
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])); \
77 } else { \
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()); \
83 } \
84 field = nullptr; \
85 }
86
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)); \
96 } \
97 } else { \
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()); \
103 } \
104 array_field.clear(); \
105 }
106
107
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; /* e.g vector<vector<int> <- > */ \
114 using T = ArrayArray::value_type::value_type; /* e.g vector<vector<int>> <- */ \
115 using E = T::element_type; \
116 array_array_field.reserve(json[json_field].size()); \
117 for (const nl::json& array: json[json_field]) { \
118 Array arr; \
119 arr.reserve(array.size()); \
120 for (const nl::json& obj: array) { \
121 arr.emplace_back(new E(obj)); \
122 } \
123 array_array_field.push_back(std::move(arr)); \
124 } \
125 } else { \
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()); \
131 } \
132 array_array_field.clear(); \
133 }