28 using std::invalid_argument::invalid_argument;
39 return fmt::format(
"At {}: {}",
pointer(), what());
47 inline void to_json(nlohmann::json& j,
const std::optional<T>& t)
56 inline void from_json(
const nlohmann::json& j, std::optional<T>& t)
65 inline void to_json(nlohmann::json& j,
const std::vector<T>& t)
67 if constexpr (std::is_same_v<T, uint8_t>)
73 j = nlohmann::json::array();
74 for (
const auto& e : t)
82 inline void from_json(
const nlohmann::json& j, std::vector<T>& t)
84 if constexpr (std::is_same_v<T, uint8_t>)
93 catch (
const std::exception& e)
96 "Vector of bytes object \"{}\" is not valid base64", j.dump()));
108 fmt::format(
"Vector object \"{}\" is not an array", j.dump()));
111 for (
size_t i = 0; i < j.size(); ++i)
115 t.push_back(j.at(i).template get<T>());
129#pragma clang diagnostic push
130#pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
132#define __FOR_JSON_COUNT_NN( \
167#define _FOR_JSON_COUNT_NN_WITH_0(...) \
168 __FOR_JSON_COUNT_NN( \
201#define _FOR_JSON_COUNT_NN(...) _FOR_JSON_COUNT_NN_WITH_0(DUMMY, ##__VA_ARGS__)
203#define _FOR_JSON_0(POP_N) _FOR_JSON_0_##POP_N
204#define _FOR_JSON_1(POP_N) _FOR_JSON_1_##POP_N
205#define _FOR_JSON_2(POP_N) _FOR_JSON_2_##POP_N
206#define _FOR_JSON_3(POP_N) _FOR_JSON_3_##POP_N
207#define _FOR_JSON_4(POP_N) _FOR_JSON_4_##POP_N
208#define _FOR_JSON_5(POP_N) _FOR_JSON_5_##POP_N
209#define _FOR_JSON_6(POP_N) _FOR_JSON_6_##POP_N
210#define _FOR_JSON_7(POP_N) _FOR_JSON_7_##POP_N
211#define _FOR_JSON_8(POP_N) _FOR_JSON_8_##POP_N
212#define _FOR_JSON_9(POP_N) _FOR_JSON_9_##POP_N
213#define _FOR_JSON_10(POP_N) _FOR_JSON_10_##POP_N
214#define _FOR_JSON_11(POP_N) _FOR_JSON_11_##POP_N
215#define _FOR_JSON_12(POP_N) _FOR_JSON_12_##POP_N
216#define _FOR_JSON_13(POP_N) _FOR_JSON_13_##POP_N
217#define _FOR_JSON_14(POP_N) _FOR_JSON_14_##POP_N
218#define _FOR_JSON_15(POP_N) _FOR_JSON_15_##POP_N
219#define _FOR_JSON_16(POP_N) _FOR_JSON_16_##POP_N
220#define _FOR_JSON_17(POP_N) _FOR_JSON_17_##POP_N
221#define _FOR_JSON_18(POP_N) _FOR_JSON_18_##POP_N
222#define _FOR_JSON_19(POP_N) _FOR_JSON_19_##POP_N
223#define _FOR_JSON_20(POP_N) _FOR_JSON_20_##POP_N
224#define _FOR_JSON_21(POP_N) _FOR_JSON_21_##POP_N
225#define _FOR_JSON_22(POP_N) _FOR_JSON_22_##POP_N
226#define _FOR_JSON_23(POP_N) _FOR_JSON_23_##POP_N
227#define _FOR_JSON_24(POP_N) _FOR_JSON_24_##POP_N
228#define _FOR_JSON_25(POP_N) _FOR_JSON_25_##POP_N
229#define _FOR_JSON_26(POP_N) _FOR_JSON_26_##POP_N
230#define _FOR_JSON_27(POP_N) _FOR_JSON_27_##POP_N
231#define _FOR_JSON_28(POP_N) _FOR_JSON_28_##POP_N
232#define _FOR_JSON_29(POP_N) _FOR_JSON_29_##POP_N
233#define _FOR_JSON_30(POP_N) _FOR_JSON_30_##POP_N
236#define _FOR_JSON_0_POP1(FUNC, TYPE)
237#define _FOR_JSON_1_POP1(FUNC, TYPE, ARG1) _FOR_JSON_FINAL(FUNC, TYPE, ARG1)
238#define _FOR_JSON_2_POP1(FUNC, TYPE, ARG1, ...) \
239 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
240 _FOR_JSON_1_POP1(FUNC, TYPE, ##__VA_ARGS__)
241#define _FOR_JSON_3_POP1(FUNC, TYPE, ARG1, ...) \
242 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
243 _FOR_JSON_2_POP1(FUNC, TYPE, ##__VA_ARGS__)
244#define _FOR_JSON_4_POP1(FUNC, TYPE, ARG1, ...) \
245 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
246 _FOR_JSON_3_POP1(FUNC, TYPE, ##__VA_ARGS__)
247#define _FOR_JSON_5_POP1(FUNC, TYPE, ARG1, ...) \
248 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
249 _FOR_JSON_4_POP1(FUNC, TYPE, ##__VA_ARGS__)
250#define _FOR_JSON_6_POP1(FUNC, TYPE, ARG1, ...) \
251 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
252 _FOR_JSON_5_POP1(FUNC, TYPE, ##__VA_ARGS__)
253#define _FOR_JSON_7_POP1(FUNC, TYPE, ARG1, ...) \
254 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
255 _FOR_JSON_6_POP1(FUNC, TYPE, ##__VA_ARGS__)
256#define _FOR_JSON_8_POP1(FUNC, TYPE, ARG1, ...) \
257 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
258 _FOR_JSON_7_POP1(FUNC, TYPE, ##__VA_ARGS__)
259#define _FOR_JSON_9_POP1(FUNC, TYPE, ARG1, ...) \
260 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
261 _FOR_JSON_8_POP1(FUNC, TYPE, ##__VA_ARGS__)
262#define _FOR_JSON_10_POP1(FUNC, TYPE, ARG1, ...) \
263 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
264 _FOR_JSON_9_POP1(FUNC, TYPE, ##__VA_ARGS__)
265#define _FOR_JSON_11_POP1(FUNC, TYPE, ARG1, ...) \
266 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
267 _FOR_JSON_10_POP1(FUNC, TYPE, ##__VA_ARGS__)
268#define _FOR_JSON_12_POP1(FUNC, TYPE, ARG1, ...) \
269 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
270 _FOR_JSON_11_POP1(FUNC, TYPE, ##__VA_ARGS__)
271#define _FOR_JSON_13_POP1(FUNC, TYPE, ARG1, ...) \
272 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
273 _FOR_JSON_12_POP1(FUNC, TYPE, ##__VA_ARGS__)
274#define _FOR_JSON_14_POP1(FUNC, TYPE, ARG1, ...) \
275 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
276 _FOR_JSON_13_POP1(FUNC, TYPE, ##__VA_ARGS__)
277#define _FOR_JSON_15_POP1(FUNC, TYPE, ARG1, ...) \
278 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
279 _FOR_JSON_14_POP1(FUNC, TYPE, ##__VA_ARGS__)
280#define _FOR_JSON_16_POP1(FUNC, TYPE, ARG1, ...) \
281 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
282 _FOR_JSON_15_POP1(FUNC, TYPE, ##__VA_ARGS__)
283#define _FOR_JSON_17_POP1(FUNC, TYPE, ARG1, ...) \
284 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
285 _FOR_JSON_16_POP1(FUNC, TYPE, ##__VA_ARGS__)
286#define _FOR_JSON_18_POP1(FUNC, TYPE, ARG1, ...) \
287 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
288 _FOR_JSON_17_POP1(FUNC, TYPE, ##__VA_ARGS__)
289#define _FOR_JSON_19_POP1(FUNC, TYPE, ARG1, ...) \
290 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
291 _FOR_JSON_18_POP1(FUNC, TYPE, ##__VA_ARGS__)
292#define _FOR_JSON_20_POP1(FUNC, TYPE, ARG1, ...) \
293 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
294 _FOR_JSON_19_POP1(FUNC, TYPE, ##__VA_ARGS__)
295#define _FOR_JSON_21_POP1(FUNC, TYPE, ARG1, ...) \
296 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
297 _FOR_JSON_20_POP1(FUNC, TYPE, ##__VA_ARGS__)
298#define _FOR_JSON_22_POP1(FUNC, TYPE, ARG1, ...) \
299 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
300 _FOR_JSON_21_POP1(FUNC, TYPE, ##__VA_ARGS__)
301#define _FOR_JSON_23_POP1(FUNC, TYPE, ARG1, ...) \
302 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
303 _FOR_JSON_22_POP1(FUNC, TYPE, ##__VA_ARGS__)
304#define _FOR_JSON_24_POP1(FUNC, TYPE, ARG1, ...) \
305 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
306 _FOR_JSON_23_POP1(FUNC, TYPE, ##__VA_ARGS__)
307#define _FOR_JSON_25_POP1(FUNC, TYPE, ARG1, ...) \
308 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
309 _FOR_JSON_24_POP1(FUNC, TYPE, ##__VA_ARGS__)
310#define _FOR_JSON_26_POP1(FUNC, TYPE, ARG1, ...) \
311 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
312 _FOR_JSON_25_POP1(FUNC, TYPE, ##__VA_ARGS__)
313#define _FOR_JSON_27_POP1(FUNC, TYPE, ARG1, ...) \
314 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
315 _FOR_JSON_26_POP1(FUNC, TYPE, ##__VA_ARGS__)
316#define _FOR_JSON_28_POP1(FUNC, TYPE, ARG1, ...) \
317 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
318 _FOR_JSON_27_POP1(FUNC, TYPE, ##__VA_ARGS__)
319#define _FOR_JSON_29_POP1(FUNC, TYPE, ARG1, ...) \
320 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
321 _FOR_JSON_28_POP1(FUNC, TYPE, ##__VA_ARGS__)
322#define _FOR_JSON_30_POP1(FUNC, TYPE, ARG1, ...) \
323 _FOR_JSON_NEXT(FUNC, TYPE, ARG1) \
324 _FOR_JSON_29_POP1(FUNC, TYPE, ##__VA_ARGS__)
327#define _FOR_JSON_0_POP2(FUNC, TYPE)
328#define _FOR_JSON_1_POP2(FUNC, TYPE, ARG1) INVALID_ODD_ARGS
329#define _FOR_JSON_2_POP2(FUNC, TYPE, ARG1, ARG2) \
330 _FOR_JSON_FINAL(FUNC, TYPE, ARG1, ARG2)
331#define _FOR_JSON_3_POP2(FUNC, TYPE, ARG1, ARG2, ...) INVALID_ODD_ARGS
332#define _FOR_JSON_4_POP2(FUNC, TYPE, ARG1, ARG2, ...) \
333 _FOR_JSON_NEXT(FUNC, TYPE, ARG1, ARG2) \
334 _FOR_JSON_2_POP2(FUNC, TYPE, ##__VA_ARGS__)
335#define _FOR_JSON_5_POP2(FUNC, TYPE, ARG1, ARG2, ...) INVALID_ODD_ARGS
336#define _FOR_JSON_6_POP2(FUNC, TYPE, ARG1, ARG2, ...) \
337 _FOR_JSON_NEXT(FUNC, TYPE, ARG1, ARG2) \
338 _FOR_JSON_4_POP2(FUNC, TYPE, ##__VA_ARGS__)
339#define _FOR_JSON_7_POP2(FUNC, TYPE, ARG1, ARG2, ...) INVALID_ODD_ARGS
340#define _FOR_JSON_8_POP2(FUNC, TYPE, ARG1, ARG2, ...) \
341 _FOR_JSON_NEXT(FUNC, TYPE, ARG1, ARG2) \
342 _FOR_JSON_6_POP2(FUNC, TYPE, ##__VA_ARGS__)
343#define _FOR_JSON_9_POP2(FUNC, TYPE, ARG1, ARG2, ...) INVALID_ODD_ARGS
344#define _FOR_JSON_10_POP2(FUNC, TYPE, ARG1, ARG2, ...) \
345 _FOR_JSON_NEXT(FUNC, TYPE, ARG1, ARG2) \
346 _FOR_JSON_8_POP2(FUNC, TYPE, ##__VA_ARGS__)
347#define _FOR_JSON_11_POP2(FUNC, TYPE, ARG1, ARG2, ...) INVALID_ODD_ARGS
348#define _FOR_JSON_12_POP2(FUNC, TYPE, ARG1, ARG2, ...) \
349 _FOR_JSON_NEXT(FUNC, TYPE, ARG1, ARG2) \
350 _FOR_JSON_10_POP2(FUNC, TYPE, ##__VA_ARGS__)
351#define _FOR_JSON_13_POP2(FUNC, TYPE, ARG1, ARG2, ...) INVALID_ODD_ARGS
352#define _FOR_JSON_14_POP2(FUNC, TYPE, ARG1, ARG2, ...) \
353 _FOR_JSON_NEXT(FUNC, TYPE, ARG1, ARG2) \
354 _FOR_JSON_12_POP2(FUNC, TYPE, ##__VA_ARGS__)
355#define _FOR_JSON_15_POP2(FUNC, TYPE, ARG1, ARG2, ...) INVALID_ODD_ARGS
356#define _FOR_JSON_16_POP2(FUNC, TYPE, ARG1, ARG2, ...) \
357 _FOR_JSON_NEXT(FUNC, TYPE, ARG1, ARG2) \
358 _FOR_JSON_14_POP2(FUNC, TYPE, ##__VA_ARGS__)
359#define _FOR_JSON_17_POP2(FUNC, TYPE, ARG1, ARG2, ...) INVALID_ODD_ARGS
360#define _FOR_JSON_18_POP2(FUNC, TYPE, ARG1, ARG2, ...) \
361 _FOR_JSON_NEXT(FUNC, TYPE, ARG1, ARG2) \
362 _FOR_JSON_16_POP2(FUNC, TYPE, ##__VA_ARGS__)
363#define _FOR_JSON_19_POP2(FUNC, TYPE, ARG1, ARG2, ...) INVALID_ODD_ARGS
364#define _FOR_JSON_20_POP2(FUNC, TYPE, ARG1, ARG2, ...) \
365 _FOR_JSON_NEXT(FUNC, TYPE, ARG1, ARG2) \
366 _FOR_JSON_18_POP2(FUNC, TYPE, ##__VA_ARGS__)
369#define _FOR_JSON_NEXT(FUNC, ...) FUNC##_FOR_JSON_NEXT(__VA_ARGS__)
370#define _FOR_JSON_FINAL(FUNC, ...) FUNC##_FOR_JSON_FINAL(__VA_ARGS__)
372#define WRITE_REQUIRED_WITH_RENAMES_FOR_JSON_NEXT(TYPE, C_FIELD, JSON_FIELD) \
374 j[JSON_FIELD] = t.C_FIELD; \
376#define WRITE_REQUIRED_WITH_RENAMES_FOR_JSON_FINAL(TYPE, C_FIELD, JSON_FIELD) \
377 WRITE_REQUIRED_WITH_RENAMES_FOR_JSON_NEXT(TYPE, C_FIELD, JSON_FIELD)
379#define WRITE_REQUIRED_FOR_JSON_NEXT(TYPE, FIELD) \
380 WRITE_REQUIRED_WITH_RENAMES_FOR_JSON_NEXT(TYPE, FIELD, #FIELD)
381#define WRITE_REQUIRED_FOR_JSON_FINAL(TYPE, FIELD) \
382 WRITE_REQUIRED_WITH_RENAMES_FOR_JSON_FINAL(TYPE, FIELD, #FIELD)
384#define WRITE_OPTIONAL_WITH_RENAMES_FOR_JSON_NEXT(TYPE, C_FIELD, JSON_FIELD) \
386 if (t.C_FIELD != t_default.C_FIELD) \
388 j[JSON_FIELD] = t.C_FIELD; \
391#define WRITE_OPTIONAL_WITH_RENAMES_FOR_JSON_FINAL(TYPE, C_FIELD, JSON_FIELD) \
392 WRITE_OPTIONAL_WITH_RENAMES_FOR_JSON_NEXT(TYPE, C_FIELD, JSON_FIELD)
394#define WRITE_OPTIONAL_FOR_JSON_NEXT(TYPE, FIELD) \
395 WRITE_OPTIONAL_WITH_RENAMES_FOR_JSON_NEXT(TYPE, FIELD, #FIELD)
396#define WRITE_OPTIONAL_FOR_JSON_FINAL(TYPE, FIELD) \
397 WRITE_OPTIONAL_WITH_RENAMES_FOR_JSON_FINAL(TYPE, FIELD, #FIELD)
399#define READ_REQUIRED_WITH_RENAMES_FOR_JSON_NEXT(TYPE, C_FIELD, JSON_FIELD) \
401 const auto it = j.find(JSON_FIELD); \
404 throw ccf::JsonParseError( \
405 "Missing required field '" JSON_FIELD "' in object: " + j.dump()); \
409 t.C_FIELD = it->get<decltype(TYPE::C_FIELD)>(); \
411 catch (ccf::JsonParseError & jpe) \
413 jpe.pointer_elements.push_back(JSON_FIELD); \
417#define READ_REQUIRED_WITH_RENAMES_FOR_JSON_FINAL(TYPE, C_FIELD, JSON_FIELD) \
418 READ_REQUIRED_WITH_RENAMES_FOR_JSON_NEXT(TYPE, C_FIELD, JSON_FIELD)
420#define READ_REQUIRED_FOR_JSON_NEXT(TYPE, FIELD) \
421 READ_REQUIRED_WITH_RENAMES_FOR_JSON_NEXT(TYPE, FIELD, #FIELD)
422#define READ_REQUIRED_FOR_JSON_FINAL(TYPE, FIELD) \
423 READ_REQUIRED_WITH_RENAMES_FOR_JSON_FINAL(TYPE, FIELD, #FIELD)
425#define READ_OPTIONAL_WITH_RENAMES_FOR_JSON_NEXT(TYPE, C_FIELD, JSON_FIELD) \
427 const auto it = j.find(JSON_FIELD); \
430 t.C_FIELD = it->get<decltype(TYPE::C_FIELD)>(); \
433#define READ_OPTIONAL_WITH_RENAMES_FOR_JSON_FINAL(TYPE, C_FIELD, JSON_FIELD) \
434 READ_OPTIONAL_WITH_RENAMES_FOR_JSON_NEXT(TYPE, C_FIELD, JSON_FIELD)
436#define READ_OPTIONAL_FOR_JSON_NEXT(TYPE, FIELD) \
437 READ_OPTIONAL_WITH_RENAMES_FOR_JSON_NEXT(TYPE, FIELD, #FIELD)
438#define READ_OPTIONAL_FOR_JSON_FINAL(TYPE, FIELD) \
439 READ_OPTIONAL_WITH_RENAMES_FOR_JSON_FINAL(TYPE, FIELD, #FIELD)
441#define FILL_SCHEMA_REQUIRED_WITH_RENAMES_FOR_JSON_NEXT( \
442 TYPE, C_FIELD, JSON_FIELD) \
443 j["properties"][JSON_FIELD] = \
444 ccf::ds::json::schema_element<decltype(TYPE::C_FIELD)>(); \
445 j["required"].push_back(JSON_FIELD);
446#define FILL_SCHEMA_REQUIRED_WITH_RENAMES_FOR_JSON_FINAL( \
447 TYPE, C_FIELD, JSON_FIELD) \
448 FILL_SCHEMA_REQUIRED_WITH_RENAMES_FOR_JSON_NEXT(TYPE, C_FIELD, JSON_FIELD)
450#define FILL_SCHEMA_REQUIRED_FOR_JSON_NEXT(TYPE, FIELD) \
451 FILL_SCHEMA_REQUIRED_WITH_RENAMES_FOR_JSON_NEXT(TYPE, FIELD, #FIELD)
452#define FILL_SCHEMA_REQUIRED_FOR_JSON_FINAL(TYPE, FIELD) \
453 FILL_SCHEMA_REQUIRED_WITH_RENAMES_FOR_JSON_FINAL(TYPE, FIELD, #FIELD)
455#define FILL_SCHEMA_OPTIONAL_WITH_RENAMES_FOR_JSON_NEXT( \
456 TYPE, C_FIELD, JSON_FIELD) \
457 j["properties"][JSON_FIELD] = \
458 ccf::ds::json::schema_element<decltype(TYPE::C_FIELD)>();
459#define FILL_SCHEMA_OPTIONAL_WITH_RENAMES_FOR_JSON_FINAL( \
460 TYPE, C_FIELD, JSON_FIELD) \
461 FILL_SCHEMA_OPTIONAL_WITH_RENAMES_FOR_JSON_NEXT(TYPE, C_FIELD, JSON_FIELD)
463#define FILL_SCHEMA_OPTIONAL_FOR_JSON_NEXT(TYPE, FIELD) \
464 FILL_SCHEMA_OPTIONAL_WITH_RENAMES_FOR_JSON_NEXT(TYPE, FIELD, #FIELD)
465#define FILL_SCHEMA_OPTIONAL_FOR_JSON_FINAL(TYPE, FIELD) \
466 FILL_SCHEMA_OPTIONAL_WITH_RENAMES_FOR_JSON_FINAL(TYPE, FIELD, #FIELD)
468#define ADD_SCHEMA_COMPONENTS_REQUIRED_WITH_RENAMES_FOR_JSON_NEXT( \
469 TYPE, C_FIELD, JSON_FIELD) \
470 j["properties"][JSON_FIELD] = \
471 doc.template add_schema_component<decltype(TYPE::C_FIELD)>(); \
472 j["required"].push_back(JSON_FIELD);
473#define ADD_SCHEMA_COMPONENTS_REQUIRED_WITH_RENAMES_FOR_JSON_FINAL( \
474 TYPE, C_FIELD, JSON_FIELD) \
475 ADD_SCHEMA_COMPONENTS_REQUIRED_WITH_RENAMES_FOR_JSON_NEXT( \
476 TYPE, C_FIELD, JSON_FIELD)
478#define ADD_SCHEMA_COMPONENTS_REQUIRED_FOR_JSON_NEXT(TYPE, FIELD) \
479 ADD_SCHEMA_COMPONENTS_REQUIRED_WITH_RENAMES_FOR_JSON_NEXT(TYPE, FIELD, #FIELD)
480#define ADD_SCHEMA_COMPONENTS_REQUIRED_FOR_JSON_FINAL(TYPE, FIELD) \
481 ADD_SCHEMA_COMPONENTS_REQUIRED_WITH_RENAMES_FOR_JSON_FINAL( \
484#define ADD_SCHEMA_COMPONENTS_OPTIONAL_WITH_RENAMES_FOR_JSON_NEXT( \
485 TYPE, C_FIELD, JSON_FIELD) \
486 j["properties"][JSON_FIELD] = \
487 doc.template add_schema_component<decltype(TYPE::C_FIELD)>();
488#define ADD_SCHEMA_COMPONENTS_OPTIONAL_WITH_RENAMES_FOR_JSON_FINAL( \
489 TYPE, C_FIELD, JSON_FIELD) \
490 ADD_SCHEMA_COMPONENTS_OPTIONAL_WITH_RENAMES_FOR_JSON_NEXT( \
491 TYPE, C_FIELD, JSON_FIELD)
493#define ADD_SCHEMA_COMPONENTS_OPTIONAL_FOR_JSON_NEXT(TYPE, FIELD) \
494 ADD_SCHEMA_COMPONENTS_OPTIONAL_WITH_RENAMES_FOR_JSON_NEXT(TYPE, FIELD, #FIELD)
495#define ADD_SCHEMA_COMPONENTS_OPTIONAL_FOR_JSON_FINAL(TYPE, FIELD) \
496 ADD_SCHEMA_COMPONENTS_OPTIONAL_WITH_RENAMES_FOR_JSON_FINAL( \
499#define JSON_FIELD_FOR_JSON_NEXT(TYPE, FIELD) \
500 ccf::JsonField<decltype(TYPE::FIELD)>{#FIELD},
501#define JSON_FIELD_FOR_JSON_FINAL(TYPE, FIELD) \
502 ccf::JsonField<decltype(TYPE::FIELD)> \
609#define DECLARE_JSON_TYPE_IMPL( \
619 void to_json_required_fields(nlohmann::json& j, const TYPE& t); \
620 void to_json_optional_fields(nlohmann::json& j, const TYPE& t); \
621 void from_json_required_fields(const nlohmann::json& j, TYPE& t); \
622 void from_json_optional_fields(const nlohmann::json& j, TYPE& t); \
623 void fill_json_schema_required_fields(nlohmann::json& j, const TYPE*); \
624 void fill_json_schema_optional_fields(nlohmann::json& j, const TYPE*); \
625 template <typename T> \
626 void add_schema_components_required_fields( \
627 T& doc, nlohmann::json& j, const TYPE*); \
628 template <typename T> \
629 void add_schema_components_optional_fields( \
630 T& doc, nlohmann::json& j, const TYPE*); \
631 inline void to_json(nlohmann::json& j, const TYPE& t) \
634 to_json_required_fields(j, t); \
637 inline void from_json(const nlohmann::json& j, TYPE& t) \
640 from_json_required_fields(j, t); \
643 inline void fill_json_schema(nlohmann::json& j, const TYPE* t) \
646 fill_json_schema_required_fields(j, t); \
649 inline std::string schema_name(const TYPE*) \
653 template <typename T> \
654 void add_schema_components(T& doc, nlohmann::json& j, const TYPE* t) \
657 add_schema_components_required_fields(doc, j, t); \
661#define DECLARE_JSON_TYPE(TYPE) DECLARE_JSON_TYPE_IMPL(TYPE, , , , , , , , )
663#define DECLARE_JSON_TYPE_WITH_BASE(TYPE, BASE) \
664 DECLARE_JSON_TYPE_IMPL( \
666 to_json(j, static_cast<const BASE&>(t)), \
668 from_json(j, static_cast<BASE&>(t)), \
670 fill_json_schema(j, static_cast<const BASE*>(t)), \
672 add_schema_components(doc, j, static_cast<const BASE*>(t)), )
674#define DECLARE_JSON_TYPE_WITH_2BASES(TYPE, BASE1, BASE2) \
675 DECLARE_JSON_TYPE_IMPL( \
676 TYPE, to_json(j, static_cast<const BASE1&>(t)); \
677 to_json(j, static_cast<const BASE2&>(t)), \
679 from_json(j, static_cast<BASE1&>(t)); \
680 from_json(j, static_cast<BASE2&>(t)), \
682 fill_json_schema(j, static_cast<const BASE1*>(t)); \
683 fill_json_schema(j, static_cast<const BASE2*>(t)), \
685 add_schema_components(doc, j, static_cast<const BASE1*>(t)); \
686 add_schema_components(doc, j, static_cast<const BASE2*>(t)), )
688#define DECLARE_JSON_TYPE_WITH_OPTIONAL_FIELDS(TYPE) \
689 DECLARE_JSON_TYPE_IMPL( \
692 to_json_optional_fields(j, t), \
694 from_json_optional_fields(j, t), \
696 fill_json_schema_optional_fields(j, t), \
698 add_schema_components_optional_fields(doc, j, t))
700#define DECLARE_JSON_TYPE_WITH_BASE_AND_OPTIONAL_FIELDS(TYPE, BASE) \
701 DECLARE_JSON_TYPE_IMPL( \
703 to_json(j, static_cast<const BASE&>(t)), \
704 to_json_optional_fields(j, t), \
705 from_json(j, static_cast<BASE&>(t)), \
706 from_json_optional_fields(j, t), \
707 fill_json_schema(j, static_cast<const BASE*>(t)), \
708 fill_json_schema_optional_fields(j, t), \
709 add_schema_components(doc, j, static_cast<const BASE*>(t)), \
710 add_schema_components_optional_fields(doc, j, t))
712#define DECLARE_JSON_REQUIRED_FIELDS(TYPE, ...) \
713 _Pragma("clang diagnostic push"); \
714 _Pragma("clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\""); \
715 inline void to_json_required_fields( \
716 nlohmann::json& j, [[maybe_unused]] const TYPE& t) \
718 if (!j.is_object()) \
720 j = nlohmann::json::object(); \
722 _FOR_JSON_COUNT_NN(__VA_ARGS__)(POP1)(WRITE_REQUIRED, TYPE, ##__VA_ARGS__) \
724 inline void from_json_required_fields( \
725 const nlohmann::json& j, [[maybe_unused]] TYPE& t) \
727 if (!j.is_object()) \
729 throw ccf::JsonParseError("Expected object, found: " + j.dump()); \
731 _FOR_JSON_COUNT_NN(__VA_ARGS__)(POP1)(READ_REQUIRED, TYPE, ##__VA_ARGS__) \
733 inline void fill_json_schema_required_fields( \
734 nlohmann::json& j, [[maybe_unused]] const TYPE*) \
736 j["type"] = "object"; \
737 _FOR_JSON_COUNT_NN(__VA_ARGS__) \
738 (POP1)(FILL_SCHEMA_REQUIRED, TYPE, ##__VA_ARGS__) \
740 template <typename T> \
741 void add_schema_components_required_fields( \
742 [[maybe_unused]] T& doc, nlohmann::json& j, [[maybe_unused]] const TYPE*) \
744 j["type"] = "object"; \
745 _FOR_JSON_COUNT_NN(__VA_ARGS__) \
746 (POP1)(ADD_SCHEMA_COMPONENTS_REQUIRED, TYPE, ##__VA_ARGS__); \
748 _Pragma("clang diagnostic pop");
750#define DECLARE_JSON_REQUIRED_FIELDS_WITH_RENAMES(TYPE, ...) \
751 inline void to_json_required_fields(nlohmann::json& j, const TYPE& t) \
753 if (!j.is_object()) \
755 j = nlohmann::json::object(); \
757 _FOR_JSON_COUNT_NN(__VA_ARGS__) \
758 (POP2)(WRITE_REQUIRED_WITH_RENAMES, TYPE, ##__VA_ARGS__) \
760 inline void from_json_required_fields(const nlohmann::json& j, TYPE& t) \
762 if (!j.is_object()) \
764 throw ccf::JsonParseError("Expected object, found: " + j.dump()); \
766 _FOR_JSON_COUNT_NN(__VA_ARGS__) \
767 (POP2)(READ_REQUIRED_WITH_RENAMES, TYPE, ##__VA_ARGS__) \
769 inline void fill_json_schema_required_fields(nlohmann::json& j, const TYPE*) \
771 j["type"] = "object"; \
772 _FOR_JSON_COUNT_NN(__VA_ARGS__) \
773 (POP2)(FILL_SCHEMA_REQUIRED_WITH_RENAMES, TYPE, ##__VA_ARGS__) \
775 template <typename T> \
776 void add_schema_components_required_fields( \
777 T& doc, nlohmann::json& j, const TYPE*) \
779 j["type"] = "object"; \
780 _FOR_JSON_COUNT_NN(__VA_ARGS__) \
781 (POP2)(ADD_SCHEMA_COMPONENTS_REQUIRED_WITH_RENAMES, TYPE, ##__VA_ARGS__); \
784#define DECLARE_JSON_OPTIONAL_FIELDS(TYPE, ...) \
785 inline void to_json_optional_fields(nlohmann::json& j, const TYPE& t) \
787 const TYPE t_default{}; \
788 _FOR_JSON_COUNT_NN(__VA_ARGS__)(POP1)(WRITE_OPTIONAL, TYPE, ##__VA_ARGS__) \
790 inline void from_json_optional_fields(const nlohmann::json& j, TYPE& t) \
792 _FOR_JSON_COUNT_NN(__VA_ARGS__)(POP1)(READ_OPTIONAL, TYPE, ##__VA_ARGS__) \
794 inline void fill_json_schema_optional_fields(nlohmann::json& j, const TYPE*) \
796 _FOR_JSON_COUNT_NN(__VA_ARGS__) \
797 (POP1)(FILL_SCHEMA_OPTIONAL, TYPE, ##__VA_ARGS__) \
799 template <typename T> \
800 void add_schema_components_optional_fields( \
801 T& doc, nlohmann::json& j, const TYPE*) \
803 _FOR_JSON_COUNT_NN(__VA_ARGS__) \
804 (POP1)(ADD_SCHEMA_COMPONENTS_OPTIONAL, TYPE, ##__VA_ARGS__); \
807#define DECLARE_JSON_OPTIONAL_FIELDS_WITH_RENAMES(TYPE, ...) \
808 inline void to_json_optional_fields(nlohmann::json& j, const TYPE& t) \
810 const TYPE t_default{}; \
811 _FOR_JSON_COUNT_NN(__VA_ARGS__) \
812 (POP2)(WRITE_OPTIONAL_WITH_RENAMES, TYPE, ##__VA_ARGS__) \
814 inline void from_json_optional_fields(const nlohmann::json& j, TYPE& t) \
816 _FOR_JSON_COUNT_NN(__VA_ARGS__) \
817 (POP2)(READ_OPTIONAL_WITH_RENAMES, TYPE, ##__VA_ARGS__) \
819 inline void fill_json_schema_optional_fields( \
820 nlohmann::json& j, [[maybe_unused]] const TYPE*) \
822 _FOR_JSON_COUNT_NN(__VA_ARGS__) \
823 (POP2)(FILL_SCHEMA_OPTIONAL_WITH_RENAMES, TYPE, ##__VA_ARGS__) \
825 template <typename T> \
826 void add_schema_components_optional_fields( \
827 T& doc, nlohmann::json& j, [[maybe_unused]] const TYPE*) \
829 _FOR_JSON_COUNT_NN(__VA_ARGS__) \
830 (POP2)(ADD_SCHEMA_COMPONENTS_OPTIONAL_WITH_RENAMES, TYPE, ##__VA_ARGS__); \
835#define DECLARE_JSON_ENUM(TYPE, ...) \
836 template <typename BasicJsonType> \
837 inline void to_json(BasicJsonType& j, const TYPE& e) \
839 static_assert(std::is_enum<TYPE>::value, #TYPE " must be an enum!"); \
840 static const std::pair<TYPE, BasicJsonType> m[] = __VA_ARGS__; \
841 auto it = std::find_if( \
844 [e](const std::pair<TYPE, BasicJsonType>& ej_pair) -> bool { \
845 return ej_pair.first == e; \
847 if (it == std::end(m)) \
849 throw ccf::JsonParseError(fmt::format( \
850 "Value {} in enum " #TYPE " has no specified JSON conversion", \
855 template <typename BasicJsonType> \
856 inline void from_json(const BasicJsonType& j, TYPE& e) \
858 static_assert(std::is_enum<TYPE>::value, #TYPE " must be an enum!"); \
859 static const std::pair<TYPE, BasicJsonType> m[] = __VA_ARGS__; \
860 auto it = std::find_if( \
863 [&j](const std::pair<TYPE, BasicJsonType>& ej_pair) -> bool { \
864 return ej_pair.second == j; \
866 if (it == std::end(m)) \
868 throw ccf::JsonParseError( \
869 fmt::format("{} is not convertible to " #TYPE, j.dump())); \
873 inline std::string schema_name(const TYPE*) \
877 inline void fill_enum_schema(nlohmann::json& j, const TYPE*) \
879 static const std::pair<TYPE, nlohmann::json> m[] = __VA_ARGS__; \
880 auto enums = nlohmann::json::array(); \
881 for (const auto& p : m) \
883 enums.push_back(p.second); \
886 j["type"] = "string"; \
889#pragma clang diagnostic pop
std::string describe() const
Definition json.h:37
std::vector< std::string > pointer_elements
Definition json.h:26
std::string pointer() const
Definition json.h:30
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:39
Definition app_interface.h:15
void to_json(nlohmann::json &j, const std::optional< T > &t)
Definition json.h:47
void from_json(const nlohmann::json &j, std::optional< T > &t)
Definition json.h:56
char const * name
Definition json.h:20
T Target
Definition json.h:19