@@ -259,18 +259,67 @@ auto sourcemeta::core::base_dialect(
259259}
260260
261261namespace {
262- auto core_vocabulary (std::string_view base_dialect) -> std::string {
262+ auto core_vocabulary_known (std::string_view base_dialect)
263+ -> sourcemeta::core::Vocabularies::Known {
263264 if (base_dialect == " https://json-schema.org/draft/2020-12/schema" ||
264265 base_dialect == " https://json-schema.org/draft/2020-12/hyper-schema" ) {
265- return " https://json-schema.org/draft/2020-12/vocab/ core" ;
266+ return sourcemeta:: core::Vocabularies::Known::JSON_Schema_2020_12_Core ;
266267 } else if (base_dialect == " https://json-schema.org/draft/2019-09/schema" ||
267268 base_dialect ==
268269 " https://json-schema.org/draft/2019-09/hyper-schema" ) {
269- return " https://json-schema.org/draft/2019-09/vocab/ core" ;
270+ return sourcemeta:: core::Vocabularies::Known::JSON_Schema_2019_09_Core ;
270271 } else {
271272 throw sourcemeta::core::SchemaBaseDialectError (std::string{base_dialect});
272273 }
273274}
275+
276+ auto dialect_to_known (std::string_view dialect)
277+ -> std::optional<sourcemeta::core::Vocabularies::Known> {
278+ using sourcemeta::core::Vocabularies;
279+ if (dialect == " http://json-schema.org/draft-07/schema#" ) {
280+ return Vocabularies::Known::JSON_Schema_Draft_7;
281+ }
282+ if (dialect == " http://json-schema.org/draft-07/hyper-schema#" ) {
283+ return Vocabularies::Known::JSON_Schema_Draft_7_Hyper;
284+ }
285+ if (dialect == " http://json-schema.org/draft-06/schema#" ) {
286+ return Vocabularies::Known::JSON_Schema_Draft_6;
287+ }
288+ if (dialect == " http://json-schema.org/draft-06/hyper-schema#" ) {
289+ return Vocabularies::Known::JSON_Schema_Draft_6_Hyper;
290+ }
291+ if (dialect == " http://json-schema.org/draft-04/schema#" ) {
292+ return Vocabularies::Known::JSON_Schema_Draft_4;
293+ }
294+ if (dialect == " http://json-schema.org/draft-04/hyper-schema#" ) {
295+ return Vocabularies::Known::JSON_Schema_Draft_4_Hyper;
296+ }
297+ if (dialect == " http://json-schema.org/draft-03/schema#" ) {
298+ return Vocabularies::Known::JSON_Schema_Draft_3;
299+ }
300+ if (dialect == " http://json-schema.org/draft-03/hyper-schema#" ) {
301+ return Vocabularies::Known::JSON_Schema_Draft_3_Hyper;
302+ }
303+ if (dialect == " http://json-schema.org/draft-02/schema#" ) {
304+ return Vocabularies::Known::JSON_Schema_Draft_2;
305+ }
306+ if (dialect == " http://json-schema.org/draft-02/hyper-schema#" ) {
307+ return Vocabularies::Known::JSON_Schema_Draft_2_Hyper;
308+ }
309+ if (dialect == " http://json-schema.org/draft-01/schema#" ) {
310+ return Vocabularies::Known::JSON_Schema_Draft_1;
311+ }
312+ if (dialect == " http://json-schema.org/draft-01/hyper-schema#" ) {
313+ return Vocabularies::Known::JSON_Schema_Draft_1_Hyper;
314+ }
315+ if (dialect == " http://json-schema.org/draft-00/schema#" ) {
316+ return Vocabularies::Known::JSON_Schema_Draft_0;
317+ }
318+ if (dialect == " http://json-schema.org/draft-00/hyper-schema#" ) {
319+ return Vocabularies::Known::JSON_Schema_Draft_0_Hyper;
320+ }
321+ return std::nullopt ;
322+ }
274323} // namespace
275324
276325auto sourcemeta::core::vocabularies (
@@ -304,21 +353,22 @@ auto sourcemeta::core::vocabularies(const SchemaResolver &resolver,
304353 // As a performance optimization shortcut
305354 if (base_dialect == dialect) {
306355 if (dialect == " https://json-schema.org/draft/2020-12/schema" ) {
307- return {{ " https://json-schema.org/draft/2020-12/vocab/core " , true },
308- { " https://json-schema.org/draft/2020-12/vocab/applicator " , true },
309- { " https://json-schema.org/draft/2020-12/vocab/unevaluated " , true },
310- { " https://json-schema.org/draft/2020-12/vocab/validation " , true },
311- { " https://json-schema.org/draft/2020-12/vocab/meta-data " , true },
312- { " https://json-schema.org/draft/2020-12/vocab/format-annotation " ,
313- true },
314- { " https://json-schema.org/draft/2020-12/vocab/content " , true }};
356+ return Vocabularies{
357+ {Vocabularies::Known::JSON_Schema_2020_12_Core , true },
358+ {Vocabularies::Known::JSON_Schema_2020_12_Applicator , true },
359+ {Vocabularies::Known::JSON_Schema_2020_12_Unevaluated , true },
360+ {Vocabularies::Known::JSON_Schema_2020_12_Validation , true },
361+ {Vocabularies::Known::JSON_Schema_2020_12_Meta_Data, true } ,
362+ {Vocabularies::Known::JSON_Schema_2020_12_Format_Annotation, true },
363+ {Vocabularies::Known::JSON_Schema_2020_12_Content , true }};
315364 } else if (dialect == " https://json-schema.org/draft/2019-09/schema" ) {
316- return {{" https://json-schema.org/draft/2019-09/vocab/core" , true },
317- {" https://json-schema.org/draft/2019-09/vocab/applicator" , true },
318- {" https://json-schema.org/draft/2019-09/vocab/validation" , true },
319- {" https://json-schema.org/draft/2019-09/vocab/meta-data" , true },
320- {" https://json-schema.org/draft/2019-09/vocab/format" , false },
321- {" https://json-schema.org/draft/2019-09/vocab/content" , true }};
365+ return Vocabularies{
366+ {Vocabularies::Known::JSON_Schema_2019_09_Core, true },
367+ {Vocabularies::Known::JSON_Schema_2019_09_Applicator, true },
368+ {Vocabularies::Known::JSON_Schema_2019_09_Validation, true },
369+ {Vocabularies::Known::JSON_Schema_2019_09_Meta_Data, true },
370+ {Vocabularies::Known::JSON_Schema_2019_09_Format, false },
371+ {Vocabularies::Known::JSON_Schema_2019_09_Content, true }};
322372 }
323373 }
324374
@@ -336,7 +386,11 @@ auto sourcemeta::core::vocabularies(const SchemaResolver &resolver,
336386 dialect == " http://json-schema.org/draft-02/schema#" ||
337387 dialect == " http://json-schema.org/draft-01/schema#" ||
338388 dialect == " http://json-schema.org/draft-00/schema#" ) {
339- return {{dialect, true }};
389+ const auto known = dialect_to_known (dialect);
390+ if (known.has_value ()) {
391+ return Vocabularies{{known.value (), true }};
392+ }
393+ return Vocabularies{{dialect, true }};
340394 }
341395
342396 /*
@@ -356,7 +410,11 @@ auto sourcemeta::core::vocabularies(const SchemaResolver &resolver,
356410 base_dialect == " http://json-schema.org/draft-02/hyper-schema#" ||
357411 base_dialect == " http://json-schema.org/draft-01/hyper-schema#" ||
358412 base_dialect == " http://json-schema.org/draft-00/hyper-schema#" ) {
359- return {{base_dialect, true }};
413+ const auto known = dialect_to_known (base_dialect);
414+ if (known.has_value ()) {
415+ return Vocabularies{{known.value (), true }};
416+ }
417+ return Vocabularies{{base_dialect, true }};
360418 }
361419
362420 /*
@@ -384,25 +442,28 @@ auto sourcemeta::core::vocabularies(const SchemaResolver &resolver,
384442 */
385443
386444 Vocabularies result;
387- const std::string core{core_vocabulary (base_dialect)};
445+ const auto core{core_vocabulary_known (base_dialect)};
388446 if (schema_dialect.defines (" $vocabulary" )) {
389447 const sourcemeta::core::JSON &vocabularies{
390448 schema_dialect.at (" $vocabulary" )};
391449 assert (vocabularies.is_object ());
392450 for (const auto &entry : vocabularies.as_object ()) {
393- result.insert ({ entry.first , entry.second .to_boolean ()} );
451+ result.insert (entry.first , entry.second .to_boolean ());
394452 }
395453 } else {
396- result.insert ({ core, true } );
454+ result.insert (core, true );
397455 }
398456
399457 // The specification recommends these checks
400458 if (!result.contains (core)) {
401459 throw sourcemeta::core::SchemaError (
402460 " The core vocabulary must always be present" );
403- } else if (!result.at (core)) {
404- throw sourcemeta::core::SchemaError (
405- " The core vocabulary must always be required" );
461+ } else {
462+ const auto core_status{result.get (core)};
463+ if (core_status.has_value () && !core_status.value ()) {
464+ throw sourcemeta::core::SchemaError (
465+ " The core vocabulary must always be required" );
466+ }
406467 }
407468
408469 return result;
0 commit comments