16 namespace json_details {
18 template<
typename JsonMember,
bool is_root =
false,
19 typename OutputIterator>
20 constexpr OutputIterator to_json_schema( ParseTag<JsonParseTypes::Bool>,
21 OutputIterator out_it ) {
22 if constexpr( not is_root ) {
26 if constexpr( not is_root ) {
32 template<
typename JsonMember,
bool is_root =
false,
33 typename OutputIterator>
34 constexpr OutputIterator to_json_schema( ParseTag<JsonParseTypes::Custom>,
35 OutputIterator out_it ) {
38 static_assert( JsonMember::custom_json_type ==
40 if constexpr( not is_root ) {
44 if constexpr( not is_root ) {
50 template<
typename JsonMember,
bool is_root =
false,
51 typename OutputIterator>
52 constexpr OutputIterator to_json_schema( ParseTag<JsonParseTypes::Date>,
53 OutputIterator out_it ) {
55 if constexpr( not is_root ) {
59 out_it, R
"("type":"string","format":"date-time")" );
60 if constexpr( not is_root ) {
66 template<
typename JsonMember,
bool is_root =
false,
67 typename OutputIterator>
68 constexpr OutputIterator to_json_schema( ParseTag<JsonParseTypes::Real>,
69 OutputIterator out_it ) {
71 if constexpr( not is_root ) {
75 if constexpr( not is_root ) {
81 template<
typename JsonMember,
bool is_root =
false,
82 typename OutputIterator>
83 constexpr OutputIterator to_json_schema( ParseTag<JsonParseTypes::Signed>,
84 OutputIterator out_it ) {
86 if constexpr( not is_root ) {
90 if constexpr( not is_root ) {
96 template<
typename JsonMember,
bool is_root =
false,
97 typename OutputIterator>
98 constexpr OutputIterator
99 to_json_schema( ParseTag<JsonParseTypes::StringEscaped>,
100 OutputIterator out_it ) {
102 if constexpr( not is_root ) {
106 if constexpr( not is_root ) {
112 template<
typename JsonMember,
bool is_root =
false,
113 typename OutputIterator>
114 constexpr OutputIterator
115 to_json_schema( ParseTag<JsonParseTypes::StringRaw>,
116 OutputIterator out_it ) {
118 if constexpr( not is_root ) {
122 if constexpr( not is_root ) {
128 template<
typename JsonMember,
bool is_root =
false,
129 typename OutputIterator>
130 constexpr OutputIterator
131 to_json_schema( ParseTag<JsonParseTypes::Unsigned>,
132 OutputIterator out_it ) {
133 if constexpr( not is_root ) {
138 if constexpr( not is_root ) {
153 template<
typename JsonMember,
bool is_root =
false,
154 typename OutputIterator>
155 constexpr OutputIterator to_json_schema( ParseTag<JsonParseTypes::Class>,
156 OutputIterator out_it );
167 template<
typename JsonMember,
bool is_root =
false,
168 typename OutputIterator>
169 constexpr OutputIterator to_json_schema( ParseTag<JsonParseTypes::Array>,
170 OutputIterator out_it );
172 template<
typename JsonMember,
bool is_root =
false,
173 typename OutputIterator>
174 constexpr OutputIterator to_json_schema( ParseTag<JsonParseTypes::Tuple>,
175 OutputIterator out_it );
177 template<
typename JsonMember,
bool is_root =
false,
178 typename OutputIterator>
179 constexpr OutputIterator
180 to_json_schema( ParseTag<JsonParseTypes::SizedArray>,
181 OutputIterator out_it );
183 template<
typename JsonMember,
bool is_root =
false,
184 typename OutputIterator>
185 constexpr OutputIterator
186 to_json_schema( ParseTag<JsonParseTypes::KeyValue>,
187 OutputIterator out_it );
189 template<
typename JsonMember,
bool is_root =
false,
190 typename OutputIterator>
191 constexpr OutputIterator
192 to_json_schema( ParseTag<JsonParseTypes::KeyValueArray>,
193 OutputIterator out_it );
195 template<
typename JsonMember,
bool is_root =
false,
196 typename OutputIterator>
197 constexpr OutputIterator
198 to_json_schema( ParseTag<JsonParseTypes::Variant>,
199 OutputIterator out_it );
201 template<
typename JsonMember,
bool is_root =
false,
202 typename OutputIterator>
203 constexpr OutputIterator
204 to_json_schema( ParseTag<JsonParseTypes::VariantTagged>,
205 OutputIterator out_it );
207 template<
typename,
typename>
208 struct json_class_processor;
210 template<
typename OutputIterator,
typename... JsonMembers>
211 struct json_class_processor<OutputIterator,
212 json_member_list<JsonMembers...>> {
214 static constexpr OutputIterator process( OutputIterator out_it ) {
216 out_it, R
"("type":"object","properties":{)" );
217 out_it = output_member_types(
218 out_it, std::index_sequence_for<JsonMembers...>{ } );
220 out_it = output_required_members( out_it );
222 if constexpr( ( has_dependent_member_v<JsonMembers> or ... ) ) {
224 bool is_first =
true;
225 out_it =
static_cast<OutputIterator
>(
227 json_link_no_name<json_link_no_name<JsonMembers>>>(
236 static constexpr
auto indexer =
237 std::index_sequence_for<JsonMembers...>{ };
239 template<
typename JsonMember, std::
size_t Idx>
240 static constexpr OutputIterator
241 output_member_type( OutputIterator &out_it,
bool &is_first,
255 out_it = to_json_schema<JsonMember>(
256 ParseTag<JsonMember::base_expected_type>{ }, out_it );
260 template<std::size_t... Is>
261 static constexpr OutputIterator
262 output_member_types( OutputIterator &out_it,
263 std::index_sequence<Is...> ) {
264 bool is_first =
true;
265 bool seen[
sizeof...( JsonMembers )]{ };
266 return static_cast<OutputIterator
>(
267 ( output_member_type<JsonMembers, Is>( out_it, is_first, seen ),
271 template<
typename JsonMember>
272 static constexpr OutputIterator
273 output_required_member( OutputIterator &out_it,
bool &is_first ) {
287 template<
typename JsonMember>
288 static constexpr OutputIterator
289 output_dependency( OutputIterator &out_it,
bool &is_first ) {
290 if constexpr( has_dependent_member_v<JsonMember> ) {
300 out_it, dependent_member_t<JsonMember>::name );
306 static constexpr OutputIterator
307 output_required_members( OutputIterator &out_it ) {
308 bool is_first =
true;
309 return ( output_required_member<json_link_no_name<JsonMembers>>(
315 template<
typename OutputIterator,
typename... JsonMembers>
316 struct json_class_processor<OutputIterator,
317 json_ordered_member_list<JsonMembers...>> {
319 static constexpr OutputIterator process( OutputIterator out_it ) {
323 out_it = output_member_types( out_it );
327 not( ( json_link_no_name<JsonMembers>::base_expected_type ==
330 "A tagged variant is not supported in a tuple/ordered json class" );
334 static constexpr OutputIterator
335 output_member_types( OutputIterator &out_it ) {
336 bool is_first =
true;
337 return static_cast<OutputIterator
>(
338 ( output_member_type<json_link_no_name<JsonMembers>>( out_it,
343 template<
typename JsonMember>
344 static constexpr OutputIterator
345 output_member_type( OutputIterator &out_it,
bool &is_first ) {
351 out_it = to_json_schema<JsonMember>(
352 ParseTag<JsonMember::base_expected_type>{ }, out_it );
357 template<
typename JsonMember,
bool is_root,
typename OutputIterator>
358 constexpr OutputIterator to_json_schema( ParseTag<JsonParseTypes::Class>,
359 OutputIterator out_it ) {
360 if constexpr( not is_root ) {
364 using json_class_processor_t = json_class_processor<
366 json_data_contract_trait_t<typename JsonMember::base_type>>;
368 out_it = json_class_processor_t::process( out_it );
370 if constexpr( not is_root ) {
376 namespace json_details {
377 template<
typename Tuple,
bool is_root,
typename OutputIterator,
379 constexpr OutputIterator
380 to_json_tuple_schema( OutputIterator out_it,
381 std::index_sequence<Is...> ) {
382 if constexpr( not is_root ) {
386 bool is_first =
true;
387 auto const process_member = [&](
auto Idx ) {
393 static constexpr std::size_t index = decltype( Idx )::value;
394 using pack_element = tuple_elements_pack<Tuple>;
396 typename pack_element::template element_t<index>>;
398 out_it = to_json_schema<JsonMember>(
399 ParseTag<JsonMember::base_expected_type>{ }, out_it );
402 daw::Empty expander[] = {
403 ( process_member( std::integral_constant<std::size_t, Is>{ } ),
408 if constexpr( not is_root ) {
415 template<
typename JsonMember,
bool is_root,
typename OutputIterator>
416 constexpr OutputIterator to_json_schema( ParseTag<JsonParseTypes::Tuple>,
417 OutputIterator out_it ) {
418 using tuple_t =
typename JsonMember::base_type;
419 return json_details::to_json_tuple_schema<tuple_t, is_root>(
421 std::make_index_sequence<tuple_elements_pack<tuple_t>::size>{ } );
424 template<
typename JsonMember,
bool is_root,
typename OutputIterator>
425 constexpr OutputIterator to_json_schema( ParseTag<JsonParseTypes::Array>,
426 OutputIterator out_it ) {
427 if constexpr( not is_root ) {
432 using element_t =
typename JsonMember::json_element_t;
433 out_it = to_json_schema<element_t>(
434 ParseTag<element_t::base_expected_type>{ }, out_it );
435 if constexpr( not is_root ) {
441 template<
typename JsonMember,
bool is_root,
typename OutputIterator>
442 constexpr OutputIterator
443 to_json_schema( ParseTag<JsonParseTypes::SizedArray>,
444 OutputIterator out_it ) {
445 return to_json_schema<JsonMember, is_root>(
446 ParseTag<JsonParseTypes::Array>{ }, out_it );
449 template<
typename JsonMember,
bool is_root,
typename OutputIterator>
450 constexpr OutputIterator
451 to_json_schema( ParseTag<JsonParseTypes::KeyValue>,
452 OutputIterator out_it ) {
453 if constexpr( not is_root ) {
457 out_it, R
"("type":"object","additionalProperties":)" );
458 using element_t =
typename JsonMember::json_element_t;
459 out_it = to_json_schema<element_t>(
460 ParseTag<element_t::base_expected_type>{ }, out_it );
461 if constexpr( not is_root ) {
467 template<
typename JsonMember,
bool is_root,
typename OutputIterator>
468 constexpr OutputIterator
469 to_json_schema( ParseTag<JsonParseTypes::KeyValueArray>,
470 OutputIterator out_it ) {
471 if constexpr( not is_root ) {
476 using element_t =
typename JsonMember::json_class_t;
477 out_it = to_json_schema<element_t>(
478 ParseTag<element_t::base_expected_type>{ }, out_it );
479 if constexpr( not is_root ) {
485 template<
typename...>
486 struct variant_element_types;
488 template<
typename... JsonElements>
489 struct variant_element_types<json_variant_type_list<JsonElements...>> {
491 template<
typename JsonElement,
typename OutputIterator>
492 static constexpr OutputIterator output_element( OutputIterator out_it,
499 return to_json_schema<JsonElement>(
500 ParseTag<JsonElement::base_expected_type>{ }, out_it );
503 template<
typename OutputIterator>
504 static constexpr OutputIterator
505 output_elements( OutputIterator out_it ) {
506 bool is_first =
true;
507 return static_cast<OutputIterator
>(
508 ( output_element<JsonElements>( out_it, is_first ), ... ) );
512 template<
typename JsonMember,
bool is_root,
typename OutputIterator>
513 constexpr OutputIterator
514 to_json_schema( ParseTag<JsonParseTypes::Variant>,
515 OutputIterator out_it ) {
516 if constexpr( not is_root ) {
520 using elements_t =
typename JsonMember::json_elements;
521 out_it = variant_element_types<elements_t>::output_elements( out_it );
523 if constexpr( not is_root ) {
529 template<
typename JsonMember,
bool is_root,
typename OutputIterator>
530 constexpr OutputIterator
531 to_json_schema( ParseTag<JsonParseTypes::VariantTagged>,
532 OutputIterator out_it ) {
533 static_assert( not is_root,
534 "Attempt to have a tagged variant as root object. This "
538 using elements_t =
typename JsonMember::json_elements;
539 out_it = variant_element_types<elements_t>::output_elements( out_it );
547 template<
typename T,
typename OutputIterator>
548 constexpr OutputIterator to_json_schema( OutputIterator out_it,
550 std::string_view title ) {
554 R
"("$schema":"https://json-schema.org/draft/2020-12/schema",)" );
561 using json_type = json_link_no_name<T>;
562 out_it = json_details::to_json_schema<json_type, true>(
563 ParseTag<json_type::base_expected_type>{ }, out_it );
569 std::string to_json_schema( std::string_view
id, std::string_view title ) {
570 auto result = std::string( );
571 (void)to_json_schema<T>( std::back_inserter( result ), id, title );
typename json_type_deducer< T, has_json_data_contract_trait_v< T >, json_details::is_a_json_type_v< T >, has_json_link_quick_map_v< T >, is_container_v< T > >::type json_deduced_type
Definition: daw_json_parse_common.h:931
constexpr OutputIterator copy_to_iterator(OutputIterator it, Container const &container)
Definition: to_daw_json_string.h:398
Definition: daw_from_json.h:22
#define DAW_JSON_VER
Definition: version.h:11