10#include <fmt/ranges.h>
30 using std::invalid_argument::invalid_argument;
41 return fmt::format(
"At {}: {}",
pointer(), what());
49 inline void to_json(nlohmann::json& j,
const std::optional<T>& t)
58 inline void from_json(
const nlohmann::json& j, std::optional<T>& t)
67 inline void to_json(nlohmann::json& j,
const std::vector<T>& t)
69 if constexpr (std::is_same_v<T, uint8_t>)
75 j = nlohmann::json::array();
76 for (
const auto& e : t)
84 inline void from_json(
const nlohmann::json& j, std::vector<T>& t)
86 if constexpr (std::is_same_v<T, uint8_t>)
95 catch (
const std::exception& e)
98 "Vector of bytes object \"{}\" is not valid base64", j.dump()));
110 fmt::format(
"Vector object \"{}\" is not an array", j.dump()));
113 for (
size_t i = 0; i < j.size(); ++i)
117 t.push_back(j.at(i).template get<T>());
131#pragma clang diagnostic push
132#pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
134#define __FOR_JSON_COUNT_NN( \
169#define _FOR_JSON_COUNT_NN_WITH_0(...) \
170 __FOR_JSON_COUNT_NN( \
203#define _FOR_JSON_COUNT_NN(...) _FOR_JSON_COUNT_NN_WITH_0(DUMMY, ##__VA_ARGS__)
205#define _FOR_JSON_0(POP_N) _FOR_JSON_0_##POP_N
206#define _FOR_JSON_1(POP_N) _FOR_JSON_1_##POP_N
207#define _FOR_JSON_2(POP_N) _FOR_JSON_2_##POP_N
208#define _FOR_JSON_3(POP_N) _FOR_JSON_3_##POP_N
209#define _FOR_JSON_4(POP_N) _FOR_JSON_4_##POP_N
210#define _FOR_JSON_5(POP_N) _FOR_JSON_5_##POP_N
211#define _FOR_JSON_6(POP_N) _FOR_JSON_6_##POP_N
212#define _FOR_JSON_7(POP_N) _FOR_JSON_7_##POP_N
213#define _FOR_JSON_8(POP_N) _FOR_JSON_8_##POP_N
214#define _FOR_JSON_9(POP_N) _FOR_JSON_9_##POP_N
215#define _FOR_JSON_10(POP_N) _FOR_JSON_10_##POP_N
216#define _FOR_JSON_11(POP_N) _FOR_JSON_11_##POP_N
217#define _FOR_JSON_12(POP_N) _FOR_JSON_12_##POP_N
218#define _FOR_JSON_13(POP_N) _FOR_JSON_13_##POP_N
219#define _FOR_JSON_14(POP_N) _FOR_JSON_14_##POP_N
220#define _FOR_JSON_15(POP_N) _FOR_JSON_15_##POP_N
221#define _FOR_JSON_16(POP_N) _FOR_JSON_16_##POP_N
222#define _FOR_JSON_17(POP_N) _FOR_JSON_17_##POP_N
223#define _FOR_JSON_18(POP_N) _FOR_JSON_18_##POP_N
224#define _FOR_JSON_19(POP_N) _FOR_JSON_19_##POP_N
225#define _FOR_JSON_20(POP_N) _FOR_JSON_20_##POP_N
226#define _FOR_JSON_21(POP_N) _FOR_JSON_21_##POP_N
227#define _FOR_JSON_22(POP_N) _FOR_JSON_22_##POP_N
228#define _FOR_JSON_23(POP_N) _FOR_JSON_23_##POP_N
229#define _FOR_JSON_24(POP_N) _FOR_JSON_24_##POP_N
230#define _FOR_JSON_25(POP_N) _FOR_JSON_25_##POP_N
231#define _FOR_JSON_26(POP_N) _FOR_JSON_26_##POP_N
232#define _FOR_JSON_27(POP_N) _FOR_JSON_27_##POP_N
233#define _FOR_JSON_28(POP_N) _FOR_JSON_28_##POP_N
234#define _FOR_JSON_29(POP_N) _FOR_JSON_29_##POP_N
235#define _FOR_JSON_30(POP_N) _FOR_JSON_30_##POP_N
238#define _FOR_JSON_0_POP1(FUNC, TYPE)
239#define _FOR_JSON_1_POP1(FUNC, TYPE, ARG1) _FOR_JSON_FINAL(FUNC, TYPE, ARG1)
240#define _FOR_JSON_2_POP1(FUNC, TYPE, ARG1, ...) \
241 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
242 _FOR_JSON_1_POP1(FUNC, TYPE, ##__VA_ARGS__)
243#define _FOR_JSON_3_POP1(FUNC, TYPE, ARG1, ...) \
244 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
245 _FOR_JSON_2_POP1(FUNC, TYPE, ##__VA_ARGS__)
246#define _FOR_JSON_4_POP1(FUNC, TYPE, ARG1, ...) \
247 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
248 _FOR_JSON_3_POP1(FUNC, TYPE, ##__VA_ARGS__)
249#define _FOR_JSON_5_POP1(FUNC, TYPE, ARG1, ...) \
250 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
251 _FOR_JSON_4_POP1(FUNC, TYPE, ##__VA_ARGS__)
252#define _FOR_JSON_6_POP1(FUNC, TYPE, ARG1, ...) \
253 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
254 _FOR_JSON_5_POP1(FUNC, TYPE, ##__VA_ARGS__)
255#define _FOR_JSON_7_POP1(FUNC, TYPE, ARG1, ...) \
256 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
257 _FOR_JSON_6_POP1(FUNC, TYPE, ##__VA_ARGS__)
258#define _FOR_JSON_8_POP1(FUNC, TYPE, ARG1, ...) \
259 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
260 _FOR_JSON_7_POP1(FUNC, TYPE, ##__VA_ARGS__)
261#define _FOR_JSON_9_POP1(FUNC, TYPE, ARG1, ...) \
262 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
263 _FOR_JSON_8_POP1(FUNC, TYPE, ##__VA_ARGS__)
264#define _FOR_JSON_10_POP1(FUNC, TYPE, ARG1, ...) \
265 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
266 _FOR_JSON_9_POP1(FUNC, TYPE, ##__VA_ARGS__)
267#define _FOR_JSON_11_POP1(FUNC, TYPE, ARG1, ...) \
268 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
269 _FOR_JSON_10_POP1(FUNC, TYPE, ##__VA_ARGS__)
270#define _FOR_JSON_12_POP1(FUNC, TYPE, ARG1, ...) \
271 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
272 _FOR_JSON_11_POP1(FUNC, TYPE, ##__VA_ARGS__)
273#define _FOR_JSON_13_POP1(FUNC, TYPE, ARG1, ...) \
274 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
275 _FOR_JSON_12_POP1(FUNC, TYPE, ##__VA_ARGS__)
276#define _FOR_JSON_14_POP1(FUNC, TYPE, ARG1, ...) \
277 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
278 _FOR_JSON_13_POP1(FUNC, TYPE, ##__VA_ARGS__)
279#define _FOR_JSON_15_POP1(FUNC, TYPE, ARG1, ...) \
280 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
281 _FOR_JSON_14_POP1(FUNC, TYPE, ##__VA_ARGS__)
282#define _FOR_JSON_16_POP1(FUNC, TYPE, ARG1, ...) \
283 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
284 _FOR_JSON_15_POP1(FUNC, TYPE, ##__VA_ARGS__)
285#define _FOR_JSON_17_POP1(FUNC, TYPE, ARG1, ...) \
286 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
287 _FOR_JSON_16_POP1(FUNC, TYPE, ##__VA_ARGS__)
288#define _FOR_JSON_18_POP1(FUNC, TYPE, ARG1, ...) \
289 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
290 _FOR_JSON_17_POP1(FUNC, TYPE, ##__VA_ARGS__)
291#define _FOR_JSON_19_POP1(FUNC, TYPE, ARG1, ...) \
292 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
293 _FOR_JSON_18_POP1(FUNC, TYPE, ##__VA_ARGS__)
294#define _FOR_JSON_20_POP1(FUNC, TYPE, ARG1, ...) \
295 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
296 _FOR_JSON_19_POP1(FUNC, TYPE, ##__VA_ARGS__)
297#define _FOR_JSON_21_POP1(FUNC, TYPE, ARG1, ...) \
298 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
299 _FOR_JSON_20_POP1(FUNC, TYPE, ##__VA_ARGS__)
300#define _FOR_JSON_22_POP1(FUNC, TYPE, ARG1, ...) \
301 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
302 _FOR_JSON_21_POP1(FUNC, TYPE, ##__VA_ARGS__)
303#define _FOR_JSON_23_POP1(FUNC, TYPE, ARG1, ...) \
304 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
305 _FOR_JSON_22_POP1(FUNC, TYPE, ##__VA_ARGS__)
306#define _FOR_JSON_24_POP1(FUNC, TYPE, ARG1, ...) \
307 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
308 _FOR_JSON_23_POP1(FUNC, TYPE, ##__VA_ARGS__)
309#define _FOR_JSON_25_POP1(FUNC, TYPE, ARG1, ...) \
310 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
311 _FOR_JSON_24_POP1(FUNC, TYPE, ##__VA_ARGS__)
312#define _FOR_JSON_26_POP1(FUNC, TYPE, ARG1, ...) \
313 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
314 _FOR_JSON_25_POP1(FUNC, TYPE, ##__VA_ARGS__)
315#define _FOR_JSON_27_POP1(FUNC, TYPE, ARG1, ...) \
316 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
317 _FOR_JSON_26_POP1(FUNC, TYPE, ##__VA_ARGS__)
318#define _FOR_JSON_28_POP1(FUNC, TYPE, ARG1, ...) \
319 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
320 _FOR_JSON_27_POP1(FUNC, TYPE, ##__VA_ARGS__)
321#define _FOR_JSON_29_POP1(FUNC, TYPE, ARG1, ...) \
322 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
323 _FOR_JSON_28_POP1(FUNC, TYPE, ##__VA_ARGS__)
324#define _FOR_JSON_30_POP1(FUNC, TYPE, ARG1, ...) \
325 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
326 _FOR_JSON_29_POP1(FUNC, TYPE, ##__VA_ARGS__)
329#define _FOR_JSON_0_POP2(FUNC, TYPE)
330#define _FOR_JSON_1_POP2(FUNC, TYPE, ARG1) INVALID_ODD_ARGS
331#define _FOR_JSON_2_POP2(FUNC, TYPE, ARG1, ARG2) \
332 _FOR_JSON_FINAL(FUNC, TYPE, ARG1, ARG2)
333#define _FOR_JSON_3_POP2(FUNC, TYPE, ARG1, ARG2, ...) INVALID_ODD_ARGS
334#define _FOR_JSON_4_POP2(FUNC, TYPE, ARG1, ARG2, ...) \
335 _FOR_JSON_NEXT(FUNC, TYPE, ARG1, ARG2) \
336 _FOR_JSON_2_POP2(FUNC, TYPE, ##__VA_ARGS__)
337#define _FOR_JSON_5_POP2(FUNC, TYPE, ARG1, ARG2, ...) INVALID_ODD_ARGS
338#define _FOR_JSON_6_POP2(FUNC, TYPE, ARG1, ARG2, ...) \
339 _FOR_JSON_NEXT(FUNC, TYPE, ARG1, ARG2) \
340 _FOR_JSON_4_POP2(FUNC, TYPE, ##__VA_ARGS__)
341#define _FOR_JSON_7_POP2(FUNC, TYPE, ARG1, ARG2, ...) INVALID_ODD_ARGS
342#define _FOR_JSON_8_POP2(FUNC, TYPE, ARG1, ARG2, ...) \
343 _FOR_JSON_NEXT(FUNC, TYPE, ARG1, ARG2) \
344 _FOR_JSON_6_POP2(FUNC, TYPE, ##__VA_ARGS__)
345#define _FOR_JSON_9_POP2(FUNC, TYPE, ARG1, ARG2, ...) INVALID_ODD_ARGS
346#define _FOR_JSON_10_POP2(FUNC, TYPE, ARG1, ARG2, ...) \
347 _FOR_JSON_NEXT(FUNC, TYPE, ARG1, ARG2) \
348 _FOR_JSON_8_POP2(FUNC, TYPE, ##__VA_ARGS__)
349#define _FOR_JSON_11_POP2(FUNC, TYPE, ARG1, ARG2, ...) INVALID_ODD_ARGS
350#define _FOR_JSON_12_POP2(FUNC, TYPE, ARG1, ARG2, ...) \
351 _FOR_JSON_NEXT(FUNC, TYPE, ARG1, ARG2) \
352 _FOR_JSON_10_POP2(FUNC, TYPE, ##__VA_ARGS__)
353#define _FOR_JSON_13_POP2(FUNC, TYPE, ARG1, ARG2, ...) INVALID_ODD_ARGS
354#define _FOR_JSON_14_POP2(FUNC, TYPE, ARG1, ARG2, ...) \
355 _FOR_JSON_NEXT(FUNC, TYPE, ARG1, ARG2) \
356 _FOR_JSON_12_POP2(FUNC, TYPE, ##__VA_ARGS__)
357#define _FOR_JSON_15_POP2(FUNC, TYPE, ARG1, ARG2, ...) INVALID_ODD_ARGS
358#define _FOR_JSON_16_POP2(FUNC, TYPE, ARG1, ARG2, ...) \
359 _FOR_JSON_NEXT(FUNC, TYPE, ARG1, ARG2) \
360 _FOR_JSON_14_POP2(FUNC, TYPE, ##__VA_ARGS__)
361#define _FOR_JSON_17_POP2(FUNC, TYPE, ARG1, ARG2, ...) INVALID_ODD_ARGS
362#define _FOR_JSON_18_POP2(FUNC, TYPE, ARG1, ARG2, ...) \
363 _FOR_JSON_NEXT(FUNC, TYPE, ARG1, ARG2) \
364 _FOR_JSON_16_POP2(FUNC, TYPE, ##__VA_ARGS__)
365#define _FOR_JSON_19_POP2(FUNC, TYPE, ARG1, ARG2, ...) INVALID_ODD_ARGS
366#define _FOR_JSON_20_POP2(FUNC, TYPE, ARG1, ARG2, ...) \
367 _FOR_JSON_NEXT(FUNC, TYPE, ARG1, ARG2) \
368 _FOR_JSON_18_POP2(FUNC, TYPE, ##__VA_ARGS__)
371#define _FOR_JSON_NEXT(FUNC, ...) FUNC##_FOR_JSON_NEXT(__VA_ARGS__)
372#define _FOR_JSON_FINAL(FUNC, ...) FUNC##_FOR_JSON_FINAL(__VA_ARGS__)
374#define WRITE_REQUIRED_WITH_RENAMES_FOR_JSON_NEXT(TYPE, C_FIELD, JSON_FIELD) \
376 j[JSON_FIELD] = t.C_FIELD; \
378#define WRITE_REQUIRED_WITH_RENAMES_FOR_JSON_FINAL(TYPE, C_FIELD, JSON_FIELD) \
379 WRITE_REQUIRED_WITH_RENAMES_FOR_JSON_NEXT(TYPE, C_FIELD, JSON_FIELD)
381#define WRITE_REQUIRED_FOR_JSON_NEXT(TYPE, FIELD) \
382 WRITE_REQUIRED_WITH_RENAMES_FOR_JSON_NEXT(TYPE, FIELD, #FIELD)
383#define WRITE_REQUIRED_FOR_JSON_FINAL(TYPE, FIELD) \
384 WRITE_REQUIRED_WITH_RENAMES_FOR_JSON_FINAL(TYPE, FIELD, #FIELD)
386#define WRITE_OPTIONAL_WITH_RENAMES_FOR_JSON_NEXT(TYPE, C_FIELD, JSON_FIELD) \
388 if (t.C_FIELD != t_default.C_FIELD) \
390 j[JSON_FIELD] = t.C_FIELD; \
393#define WRITE_OPTIONAL_WITH_RENAMES_FOR_JSON_FINAL(TYPE, C_FIELD, JSON_FIELD) \
394 WRITE_OPTIONAL_WITH_RENAMES_FOR_JSON_NEXT(TYPE, C_FIELD, JSON_FIELD)
396#define WRITE_OPTIONAL_FOR_JSON_NEXT(TYPE, FIELD) \
397 WRITE_OPTIONAL_WITH_RENAMES_FOR_JSON_NEXT(TYPE, FIELD, #FIELD)
398#define WRITE_OPTIONAL_FOR_JSON_FINAL(TYPE, FIELD) \
399 WRITE_OPTIONAL_WITH_RENAMES_FOR_JSON_FINAL(TYPE, FIELD, #FIELD)
401#define READ_REQUIRED_WITH_RENAMES_FOR_JSON_NEXT(TYPE, C_FIELD, JSON_FIELD) \
403 const auto it = j.find(JSON_FIELD); \
406 throw ccf::JsonParseError( \
407 "Missing required field '" JSON_FIELD "' in object: " + j.dump()); \
411 t.C_FIELD = it->get<decltype(TYPE::C_FIELD)>(); \
413 catch (ccf::JsonParseError & jpe) \
415 jpe.pointer_elements.emplace_back(JSON_FIELD); \
419#define READ_REQUIRED_WITH_RENAMES_FOR_JSON_FINAL(TYPE, C_FIELD, JSON_FIELD) \
420 READ_REQUIRED_WITH_RENAMES_FOR_JSON_NEXT(TYPE, C_FIELD, JSON_FIELD)
422#define READ_REQUIRED_FOR_JSON_NEXT(TYPE, FIELD) \
423 READ_REQUIRED_WITH_RENAMES_FOR_JSON_NEXT(TYPE, FIELD, #FIELD)
424#define READ_REQUIRED_FOR_JSON_FINAL(TYPE, FIELD) \
425 READ_REQUIRED_WITH_RENAMES_FOR_JSON_FINAL(TYPE, FIELD, #FIELD)
427#define READ_OPTIONAL_WITH_RENAMES_FOR_JSON_NEXT(TYPE, C_FIELD, JSON_FIELD) \
429 const auto it = j.find(JSON_FIELD); \
432 t.C_FIELD = it->get<decltype(TYPE::C_FIELD)>(); \
435#define READ_OPTIONAL_WITH_RENAMES_FOR_JSON_FINAL(TYPE, C_FIELD, JSON_FIELD) \
436 READ_OPTIONAL_WITH_RENAMES_FOR_JSON_NEXT(TYPE, C_FIELD, JSON_FIELD)
438#define READ_OPTIONAL_FOR_JSON_NEXT(TYPE, FIELD) \
439 READ_OPTIONAL_WITH_RENAMES_FOR_JSON_NEXT(TYPE, FIELD, #FIELD)
440#define READ_OPTIONAL_FOR_JSON_FINAL(TYPE, FIELD) \
441 READ_OPTIONAL_WITH_RENAMES_FOR_JSON_FINAL(TYPE, FIELD, #FIELD)
443#define FILL_SCHEMA_REQUIRED_WITH_RENAMES_FOR_JSON_NEXT( \
444 TYPE, C_FIELD, JSON_FIELD) \
445 j["properties"][JSON_FIELD] = \
446 ccf::ds::json::schema_element<decltype(TYPE::C_FIELD)>(); \
447 j["required"].push_back(JSON_FIELD);
448#define FILL_SCHEMA_REQUIRED_WITH_RENAMES_FOR_JSON_FINAL( \
449 TYPE, C_FIELD, JSON_FIELD) \
450 FILL_SCHEMA_REQUIRED_WITH_RENAMES_FOR_JSON_NEXT(TYPE, C_FIELD, JSON_FIELD)
452#define FILL_SCHEMA_REQUIRED_FOR_JSON_NEXT(TYPE, FIELD) \
453 FILL_SCHEMA_REQUIRED_WITH_RENAMES_FOR_JSON_NEXT(TYPE, FIELD, #FIELD)
454#define FILL_SCHEMA_REQUIRED_FOR_JSON_FINAL(TYPE, FIELD) \
455 FILL_SCHEMA_REQUIRED_WITH_RENAMES_FOR_JSON_FINAL(TYPE, FIELD, #FIELD)
457#define FILL_SCHEMA_OPTIONAL_WITH_RENAMES_FOR_JSON_NEXT( \
458 TYPE, C_FIELD, JSON_FIELD) \
459 j["properties"][JSON_FIELD] = \
460 ccf::ds::json::schema_element<decltype(TYPE::C_FIELD)>();
461#define FILL_SCHEMA_OPTIONAL_WITH_RENAMES_FOR_JSON_FINAL( \
462 TYPE, C_FIELD, JSON_FIELD) \
463 FILL_SCHEMA_OPTIONAL_WITH_RENAMES_FOR_JSON_NEXT(TYPE, C_FIELD, JSON_FIELD)
465#define FILL_SCHEMA_OPTIONAL_FOR_JSON_NEXT(TYPE, FIELD) \
466 FILL_SCHEMA_OPTIONAL_WITH_RENAMES_FOR_JSON_NEXT(TYPE, FIELD, #FIELD)
467#define FILL_SCHEMA_OPTIONAL_FOR_JSON_FINAL(TYPE, FIELD) \
468 FILL_SCHEMA_OPTIONAL_WITH_RENAMES_FOR_JSON_FINAL(TYPE, FIELD, #FIELD)
470#define ADD_SCHEMA_COMPONENTS_REQUIRED_WITH_RENAMES_FOR_JSON_NEXT( \
471 TYPE, C_FIELD, JSON_FIELD) \
472 j["properties"][JSON_FIELD] = \
473 doc.template add_schema_component<decltype(TYPE::C_FIELD)>(); \
474 j["required"].push_back(JSON_FIELD);
475#define ADD_SCHEMA_COMPONENTS_REQUIRED_WITH_RENAMES_FOR_JSON_FINAL( \
476 TYPE, C_FIELD, JSON_FIELD) \
477 ADD_SCHEMA_COMPONENTS_REQUIRED_WITH_RENAMES_FOR_JSON_NEXT( \
478 TYPE, C_FIELD, JSON_FIELD)
480#define ADD_SCHEMA_COMPONENTS_REQUIRED_FOR_JSON_NEXT(TYPE, FIELD) \
481 ADD_SCHEMA_COMPONENTS_REQUIRED_WITH_RENAMES_FOR_JSON_NEXT(TYPE, FIELD, #FIELD)
482#define ADD_SCHEMA_COMPONENTS_REQUIRED_FOR_JSON_FINAL(TYPE, FIELD) \
483 ADD_SCHEMA_COMPONENTS_REQUIRED_WITH_RENAMES_FOR_JSON_FINAL( \
486#define ADD_SCHEMA_COMPONENTS_OPTIONAL_WITH_RENAMES_FOR_JSON_NEXT( \
487 TYPE, C_FIELD, JSON_FIELD) \
488 j["properties"][JSON_FIELD] = \
489 doc.template add_schema_component<decltype(TYPE::C_FIELD)>();
490#define ADD_SCHEMA_COMPONENTS_OPTIONAL_WITH_RENAMES_FOR_JSON_FINAL( \
491 TYPE, C_FIELD, JSON_FIELD) \
492 ADD_SCHEMA_COMPONENTS_OPTIONAL_WITH_RENAMES_FOR_JSON_NEXT( \
493 TYPE, C_FIELD, JSON_FIELD)
495#define ADD_SCHEMA_COMPONENTS_OPTIONAL_FOR_JSON_NEXT(TYPE, FIELD) \
496 ADD_SCHEMA_COMPONENTS_OPTIONAL_WITH_RENAMES_FOR_JSON_NEXT(TYPE, FIELD, #FIELD)
497#define ADD_SCHEMA_COMPONENTS_OPTIONAL_FOR_JSON_FINAL(TYPE, FIELD) \
498 ADD_SCHEMA_COMPONENTS_OPTIONAL_WITH_RENAMES_FOR_JSON_FINAL( \
501#define JSON_FIELD_FOR_JSON_NEXT(TYPE, FIELD) \
502 ccf::JsonField<decltype(TYPE::FIELD)>{#FIELD},
503#define JSON_FIELD_FOR_JSON_FINAL(TYPE, FIELD) \
504 ccf::JsonField<decltype(TYPE::FIELD)> \
611#define DECLARE_JSON_TYPE_IMPL( \
621 void to_json_required_fields(nlohmann::json& j, const TYPE& t); \
622 void to_json_optional_fields(nlohmann::json& j, const TYPE& t); \
623 void from_json_required_fields(const nlohmann::json& j, TYPE& t); \
624 void from_json_optional_fields(const nlohmann::json& j, TYPE& t); \
625 void fill_json_schema_required_fields(nlohmann::json& j, const TYPE*); \
626 void fill_json_schema_optional_fields(nlohmann::json& j, const TYPE*); \
627 template <typename T> \
628 void add_schema_components_required_fields( \
629 T& doc, nlohmann::json& j, const TYPE*); \
630 template <typename T> \
631 void add_schema_components_optional_fields( \
632 T& doc, nlohmann::json& j, const TYPE*); \
633 inline void to_json(nlohmann::json& j, const TYPE& t) \
636 to_json_required_fields(j, t); \
639 inline void from_json(const nlohmann::json& j, TYPE& t) \
642 from_json_required_fields(j, t); \
645 inline void fill_json_schema(nlohmann::json& j, const TYPE* t) \
648 fill_json_schema_required_fields(j, t); \
651 inline std::string schema_name(const TYPE*) \
655 template <typename T> \
656 void add_schema_components(T& doc, nlohmann::json& j, const TYPE* t) \
659 add_schema_components_required_fields(doc, j, t); \
663#define DECLARE_JSON_TYPE(TYPE) DECLARE_JSON_TYPE_IMPL(TYPE, , , , , , , , )
665#define DECLARE_JSON_TYPE_WITH_BASE(TYPE, BASE) \
666 DECLARE_JSON_TYPE_IMPL( \
668 to_json(j, static_cast<const BASE&>(t)), \
670 from_json(j, static_cast<BASE&>(t)), \
672 fill_json_schema(j, static_cast<const BASE*>(t)), \
674 add_schema_components(doc, j, static_cast<const BASE*>(t)), )
676#define DECLARE_JSON_TYPE_WITH_2BASES(TYPE, BASE1, BASE2) \
677 DECLARE_JSON_TYPE_IMPL( \
678 TYPE, to_json(j, static_cast<const BASE1&>(t)); \
679 to_json(j, static_cast<const BASE2&>(t)), \
681 from_json(j, static_cast<BASE1&>(t)); \
682 from_json(j, static_cast<BASE2&>(t)), \
684 fill_json_schema(j, static_cast<const BASE1*>(t)); \
685 fill_json_schema(j, static_cast<const BASE2*>(t)), \
687 add_schema_components(doc, j, static_cast<const BASE1*>(t)); \
688 add_schema_components(doc, j, static_cast<const BASE2*>(t)), )
690#define DECLARE_JSON_TYPE_WITH_OPTIONAL_FIELDS(TYPE) \
691 DECLARE_JSON_TYPE_IMPL( \
694 to_json_optional_fields(j, t), \
696 from_json_optional_fields(j, t), \
698 fill_json_schema_optional_fields(j, t), \
700 add_schema_components_optional_fields(doc, j, t))
702#define DECLARE_JSON_TYPE_WITH_BASE_AND_OPTIONAL_FIELDS(TYPE, BASE) \
703 DECLARE_JSON_TYPE_IMPL( \
705 to_json(j, static_cast<const BASE&>(t)), \
706 to_json_optional_fields(j, t), \
707 from_json(j, static_cast<BASE&>(t)), \
708 from_json_optional_fields(j, t), \
709 fill_json_schema(j, static_cast<const BASE*>(t)), \
710 fill_json_schema_optional_fields(j, t), \
711 add_schema_components(doc, j, static_cast<const BASE*>(t)), \
712 add_schema_components_optional_fields(doc, j, t))
714#define DECLARE_JSON_REQUIRED_FIELDS(TYPE, ...) \
715 _Pragma("clang diagnostic push"); \
716 _Pragma("clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\""); \
717 inline void to_json_required_fields( \
718 nlohmann::json& j, [[maybe_unused]] const TYPE& t) \
720 if (!j.is_object()) \
722 j = nlohmann::json::object(); \
724 _FOR_JSON_COUNT_NN(__VA_ARGS__)(POP1)(WRITE_REQUIRED, TYPE, ##__VA_ARGS__) \
726 inline void from_json_required_fields( \
727 const nlohmann::json& j, [[maybe_unused]] TYPE& t) \
729 if (!j.is_object()) \
731 throw ccf::JsonParseError("Expected object, found: " + j.dump()); \
733 _FOR_JSON_COUNT_NN(__VA_ARGS__)(POP1)(READ_REQUIRED, TYPE, ##__VA_ARGS__) \
735 inline void fill_json_schema_required_fields( \
736 nlohmann::json& j, [[maybe_unused]] const TYPE*) \
738 j["type"] = "object"; \
739 _FOR_JSON_COUNT_NN(__VA_ARGS__) \
740 (POP1)(FILL_SCHEMA_REQUIRED, TYPE, ##__VA_ARGS__) \
742 template <typename T> \
743 void add_schema_components_required_fields( \
744 [[maybe_unused]] T& doc, nlohmann::json& j, [[maybe_unused]] const TYPE*) \
746 j["type"] = "object"; \
747 _FOR_JSON_COUNT_NN(__VA_ARGS__) \
748 (POP1)(ADD_SCHEMA_COMPONENTS_REQUIRED, TYPE, ##__VA_ARGS__); \
750 _Pragma("clang diagnostic pop");
752#define DECLARE_JSON_REQUIRED_FIELDS_WITH_RENAMES(TYPE, ...) \
753 inline void to_json_required_fields(nlohmann::json& j, const TYPE& t) \
755 if (!j.is_object()) \
757 j = nlohmann::json::object(); \
759 _FOR_JSON_COUNT_NN(__VA_ARGS__) \
760 (POP2)(WRITE_REQUIRED_WITH_RENAMES, TYPE, ##__VA_ARGS__) \
762 inline void from_json_required_fields(const nlohmann::json& j, TYPE& t) \
764 if (!j.is_object()) \
766 throw ccf::JsonParseError("Expected object, found: " + j.dump()); \
768 _FOR_JSON_COUNT_NN(__VA_ARGS__) \
769 (POP2)(READ_REQUIRED_WITH_RENAMES, TYPE, ##__VA_ARGS__) \
771 inline void fill_json_schema_required_fields(nlohmann::json& j, const TYPE*) \
773 j["type"] = "object"; \
774 _FOR_JSON_COUNT_NN(__VA_ARGS__) \
775 (POP2)(FILL_SCHEMA_REQUIRED_WITH_RENAMES, TYPE, ##__VA_ARGS__) \
777 template <typename T> \
778 void add_schema_components_required_fields( \
779 T& doc, nlohmann::json& j, const TYPE*) \
781 j["type"] = "object"; \
782 _FOR_JSON_COUNT_NN(__VA_ARGS__) \
783 (POP2)(ADD_SCHEMA_COMPONENTS_REQUIRED_WITH_RENAMES, TYPE, ##__VA_ARGS__); \
786#define DECLARE_JSON_OPTIONAL_FIELDS(TYPE, ...) \
787 inline void to_json_optional_fields(nlohmann::json& j, const TYPE& t) \
789 const TYPE t_default{}; \
790 _FOR_JSON_COUNT_NN(__VA_ARGS__)(POP1)(WRITE_OPTIONAL, TYPE, ##__VA_ARGS__) \
792 inline void from_json_optional_fields(const nlohmann::json& j, TYPE& t) \
794 _FOR_JSON_COUNT_NN(__VA_ARGS__)(POP1)(READ_OPTIONAL, TYPE, ##__VA_ARGS__) \
796 inline void fill_json_schema_optional_fields(nlohmann::json& j, const TYPE*) \
798 _FOR_JSON_COUNT_NN(__VA_ARGS__) \
799 (POP1)(FILL_SCHEMA_OPTIONAL, TYPE, ##__VA_ARGS__) \
801 template <typename T> \
802 void add_schema_components_optional_fields( \
803 T& doc, nlohmann::json& j, const TYPE*) \
805 _FOR_JSON_COUNT_NN(__VA_ARGS__) \
806 (POP1)(ADD_SCHEMA_COMPONENTS_OPTIONAL, TYPE, ##__VA_ARGS__); \
809#define DECLARE_JSON_OPTIONAL_FIELDS_WITH_RENAMES(TYPE, ...) \
810 inline void to_json_optional_fields(nlohmann::json& j, const TYPE& t) \
812 const TYPE t_default{}; \
813 _FOR_JSON_COUNT_NN(__VA_ARGS__) \
814 (POP2)(WRITE_OPTIONAL_WITH_RENAMES, TYPE, ##__VA_ARGS__) \
816 inline void from_json_optional_fields(const nlohmann::json& j, TYPE& t) \
818 _FOR_JSON_COUNT_NN(__VA_ARGS__) \
819 (POP2)(READ_OPTIONAL_WITH_RENAMES, TYPE, ##__VA_ARGS__) \
821 inline void fill_json_schema_optional_fields( \
822 nlohmann::json& j, [[maybe_unused]] const TYPE*) \
824 _FOR_JSON_COUNT_NN(__VA_ARGS__) \
825 (POP2)(FILL_SCHEMA_OPTIONAL_WITH_RENAMES, TYPE, ##__VA_ARGS__) \
827 template <typename T> \
828 void add_schema_components_optional_fields( \
829 T& doc, nlohmann::json& j, [[maybe_unused]] const TYPE*) \
831 _FOR_JSON_COUNT_NN(__VA_ARGS__) \
832 (POP2)(ADD_SCHEMA_COMPONENTS_OPTIONAL_WITH_RENAMES, TYPE, ##__VA_ARGS__); \
837#define DECLARE_JSON_ENUM(TYPE, ...) \
838 template <typename BasicJsonType> \
839 inline void to_json(BasicJsonType& j, const TYPE& e) \
841 static_assert(std::is_enum<TYPE>::value, #TYPE " must be an enum!"); \
842 static const std::pair<TYPE, BasicJsonType> m[] = __VA_ARGS__; \
843 auto it = std::find_if( \
846 [e](const std::pair<TYPE, BasicJsonType>& ej_pair) -> bool { \
847 return ej_pair.first == e; \
849 if (it == std::end(m)) \
851 throw ccf::JsonParseError(fmt::format( \
852 "Value {} in enum " #TYPE " has no specified JSON conversion", \
857 template <typename BasicJsonType> \
858 inline void from_json(const BasicJsonType& j, TYPE& e) \
860 static_assert(std::is_enum<TYPE>::value, #TYPE " must be an enum!"); \
861 static const std::pair<TYPE, BasicJsonType> m[] = __VA_ARGS__; \
862 auto it = std::find_if( \
865 [&j](const std::pair<TYPE, BasicJsonType>& ej_pair) -> bool { \
866 return ej_pair.second == j; \
868 if (it == std::end(m)) \
870 throw ccf::JsonParseError( \
871 fmt::format("{} is not convertible to " #TYPE, j.dump())); \
875 inline std::string schema_name(const TYPE*) \
879 inline void fill_enum_schema(nlohmann::json& j, const TYPE*) \
881 static const std::pair<TYPE, nlohmann::json> m[] = __VA_ARGS__; \
882 auto enums = nlohmann::json::array(); \
883 for (const auto& p : m) \
885 enums.push_back(p.second); \
888 j["type"] = "string"; \
891#pragma clang diagnostic pop
std::string describe() const
Definition json.h:39
std::vector< std::string > pointer_elements
Definition json.h:28
std::string pointer() const
Definition json.h:32
std::vector< uint8_t > raw_from_b64(const std::string_view &b64_string)
Definition base64.cpp:12
std::string b64_from_raw(const uint8_t *data, size_t size)
Definition base64.cpp:41
Definition app_interface.h:14
void to_json(nlohmann::json &j, const std::optional< T > &t)
Definition json.h:49
void from_json(const nlohmann::json &j, std::optional< T > &t)
Definition json.h:58
char const * name
Definition json.h:22
T Target
Definition json.h:21