tgbotxx
1.2.9.5
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>
14
namespace
nl = nlohmann;
15
17
18
20
#define TGBOTXX_CAT_IMPL(a, b) a##b
21
#define TGBOTXX_CAT(a, b) TGBOTXX_CAT_IMPL(a, b)
22
24
#define VAR(x) TGBOTXX_CAT(x, __LINE__)
25
27
#define OBJECT_SERIALIZE_FIELD(json, json_field, field) \
28
do { \
29
json[json_field] = field; \
30
} while (false)
31
32
#define OBJECT_SERIALIZE_FIELD_PTR(json, json_field, field) \
33
do { \
34
if (field) { \
35
json[json_field] = (field)->toJson(); \
36
} \
37
} while (false)
38
39
#define OBJECT_SERIALIZE_FIELD_PTR_ARRAY(json, json_field, array_field) \
40
do { \
41
auto arr = json[json_field] = nl::json::array(); \
42
for (const auto& e: array_field) \
43
arr.emplace_back(e->toJson()); \
44
} while (false)
45
46
#define OBJECT_SERIALIZE_FIELD_PTR_ARRAY_ARRAY(json, json_field, array_array_field) \
47
do { \
48
auto& root_arr = json[json_field] = nl::json::array(); \
49
for (const auto& array: array_array_field) { \
50
nl::json arr = nl::json::array(); \
51
for (const auto& e: array) { \
52
arr.emplace_back(e->toJson()); \
53
} \
54
root_arr.emplace_back(arr); \
55
} \
56
} while (false)
57
58
#define OBJECT_SERIALIZE_FIELD_ENUM(json, enum_name, json_field, field) \
59
do { \
60
json[json_field] = TGBOTXX_CAT(enum_name, ToString)(field); \
61
} while (false)
62
64
#define OBJECT_DESERIALIZE_FIELD(json, json_field, field, default_value, optional) \
65
do { \
66
if (json.contains(json_field)) { \
67
try { \
68
using T = std::remove_reference_t<std::remove_const_t<decltype(field)>>; \
69
field = json[json_field].get<T>(); \
70
} catch (const std::exception& e) { \
71
std::ostringstream err{}; \
72
err << __FILE__ << ':' << __LINE__ << ": " << __FUNCTION__ << ": Failed to deserialize \"" \
73
<< json_field << "\" from json object: " << json.dump(2) << "\nReason: " << e.what(); \
74
throw Exception(err.str()); \
75
} catch (...) { \
76
std::ostringstream err{}; \
77
err << __FILE__ << ':' << __LINE__ << ": " << __FUNCTION__ << ": Failed to deserialize \"" \
78
<< json_field << "\" from json object: " << json.dump(2); \
79
throw Exception(err.str()); \
80
} \
81
} else { \
82
if (not(optional)) { \
83
std::ostringstream err{}; \
84
err << __FILE__ << ':' << __LINE__ << ": " << __FUNCTION__ << ": Missing required field \"" \
85
<< json_field << "\" from json object: " << json.dump(2); \
86
throw Exception(err.str()); \
87
} \
88
field = default_value; \
89
} \
90
} while (false)
91
92
#define OBJECT_DESERIALIZE_FIELD_PTR(json, json_field, field, optional) \
93
do { \
94
static_assert(!std::is_const_v<decltype(field)>, "OBJECT_DESERIALIZE_FIELD_PTR: 'field' must not be const"); \
95
static_assert(std::is_same_v<decltype(optional), bool>, "OBJECT_DESERIALIZE_FIELD_PTR: 'optional' must be boolean"); \
96
if (json.contains(json_field) and json[json_field].is_object() and not json[json_field].empty()) { \
97
using T = std::remove_reference_t<decltype(field)>; \
98
using E = T::element_type; \
99
field = makePtr<E>(json[json_field]); \
100
} else { \
101
if (not(optional)) { \
102
std::ostringstream err{}; \
103
err << __FILE__ << ':' << __LINE__ << ": " << __FUNCTION__ << ": Missing required field \"" \
104
<< json_field << "\" from json object: " << json.dump(2); \
105
throw Exception(err.str()); \
106
} \
107
field = nullptr; \
108
} \
109
} while (false)
110
111
#define OBJECT_DESERIALIZE_FIELD_PTR_ARRAY(json, json_field, array_field, optional) \
112
do { \
113
static_assert(!std::is_const_v<decltype(array_field)>, "OBJECT_DESERIALIZE_FIELD_PTR_ARRAY: 'field' must not be const"); \
114
static_assert(std::is_same_v<decltype(optional), bool>, "OBJECT_DESERIALIZE_FIELD_PTR_ARRAY: 'optional' must be boolean"); \
115
if ((json.contains(json_field)) and (json[json_field].is_array())) { \
116
using T = std::remove_reference_t<std::remove_const_t<decltype(array_field)::value_type>>; \
117
using E = T::element_type; \
118
array_field.clear(); \
119
array_field.reserve(json[json_field].size()); \
120
for (const nl::json& obj: json[json_field]) { \
121
array_field.emplace_back(new E(obj)); \
122
} \
123
} else { \
124
if (not(optional)) { \
125
std::ostringstream err{}; \
126
err << __FILE__ << ':' << __LINE__ << ": " << __FUNCTION__ << ": Missing required field \"" \
127
<< json_field << "\" from json object: " << json.dump(2); \
128
throw Exception(err.str()); \
129
} \
130
array_field.clear(); \
131
} \
132
} while (false)
133
134
135
#define OBJECT_DESERIALIZE_FIELD_PTR_ARRAY_ARRAY(json, json_field, array_array_field, optional) \
136
do { \
137
static_assert(!std::is_const_v<decltype(array_array_field)>, "OBJECT_DESERIALIZE_FIELD_PTR_ARRAY_ARRAY: 'field' must not be const"); \
138
static_assert(std::is_same_v<decltype(optional), bool>, "OBJECT_DESERIALIZE_FIELD_PTR_ARRAY_ARRAY: 'optional' must be boolean"); \
139
if ((json.contains(json_field)) and (json[json_field].is_array())) { \
140
using ArrayArray = decltype(array_array_field); \
141
using Array = ArrayArray::value_type;
/* e.g vector<vector<int> <- > */
\
142
using T = ArrayArray::value_type::value_type;
/* e.g vector<vector<int>> <- */
\
143
using E = T::element_type; \
144
array_array_field.clear(); \
145
array_array_field.reserve(json[json_field].size()); \
146
for (const nl::json& array: json[json_field]) { \
147
Array arr; \
148
arr.reserve(array.size()); \
149
for (const nl::json& obj: array) { \
150
arr.emplace_back(new E(obj)); \
151
} \
152
array_array_field.emplace_back(std::move(arr)); \
153
} \
154
} else { \
155
if (not(optional)) { \
156
std::ostringstream err{}; \
157
err << __FILE__ << ':' << __LINE__ << ": " << __FUNCTION__ << ": Missing required field \"" \
158
<< json_field << "\" from json object: " << json.dump(2); \
159
throw Exception(err.str()); \
160
} \
161
array_array_field.clear(); \
162
} \
163
} while (false)
164
165
#define OBJECT_DESERIALIZE_FIELD_ENUM(json, enum_name, json_field, field, default_value, optional) \
166
do { \
167
static_assert(std::is_enum_v<decltype(field)>, "OBJECT_DESERIALIZE_FIELD_ENUM: 'field' must be an enum"); \
168
static_assert(!std::is_const_v<decltype(field)>, "OBJECT_DESERIALIZE_FIELD_ENUM: 'field' must not be const"); \
169
if (json.contains(json_field)) { \
170
try { \
171
if (auto opt = TGBOTXX_CAT(StringTo, enum_name)(json[json_field])) \
172
field = *opt; \
173
else \
174
throw Exception("Could not convert string \"" + json[json_field].get<std::string>() + "\" to enum"); \
175
} catch (const std::exception& e) { \
176
std::ostringstream err{}; \
177
err << __FILE__ << ':' << __LINE__ << ": " << __FUNCTION__ << ": Failed to deserialize \"" \
178
<< json_field << "\" from json object: " << json.dump(2) << "\nReason: " << e.what(); \
179
throw Exception(err.str()); \
180
} catch (...) { \
181
std::ostringstream err{}; \
182
err << __FILE__ << ':' << __LINE__ << ": " << __FUNCTION__ << ": Failed to deserialize \"" \
183
<< json_field << "\" from json object: " << json.dump(2); \
184
throw Exception(err.str()); \
185
} \
186
} else { \
187
if (not(optional)) { \
188
std::ostringstream err{}; \
189
err << __FILE__ << ':' << __LINE__ << ": " << __FUNCTION__ << ": Missing required field \"" \
190
<< json_field << "\" from json object: " << json.dump(2); \
191
throw Exception(err.str()); \
192
} \
193
field = static_cast<enum_name>(default_value); \
194
} \
195
} while (false)
Exception.hpp
Ptr.hpp
include
tgbotxx
objects
Object.hpp
Generated on Sun Mar 22 2026 21:33:30 for tgbotxx by
1.9.8