corvus_json_schema/
dialect.rs1#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
5pub enum Dialect {
6 Draft4,
7 Draft6,
8 Draft7,
9 Draft201909,
10 Draft202012,
11}
12
13impl Dialect {
14 pub(crate) fn is_legacy(self) -> bool {
16 self <= Dialect::Draft7
17 }
18}
19
20pub(crate) mod vocab {
22 pub const NONE: u32 = 0;
23 pub const CORE: u32 = 1 << 0;
24 pub const APPLICATOR: u32 = 1 << 1;
25 pub const VALIDATION: u32 = 1 << 2;
26 pub const META_DATA: u32 = 1 << 3;
27 pub const FORMAT_ANNOTATION: u32 = 1 << 4;
28 pub const FORMAT_ASSERTION: u32 = 1 << 5;
29 pub const CONTENT: u32 = 1 << 6;
30 pub const UNEVALUATED: u32 = 1 << 7;
31 pub const ALL_ANNOTATING_FORMAT: u32 =
32 CORE | APPLICATOR | VALIDATION | META_DATA | FORMAT_ANNOTATION | CONTENT | UNEVALUATED;
33}
34
35pub(crate) fn known_dialect(uri: &str) -> Option<Dialect> {
37 match uri {
38 "http://json-schema.org/draft-04/schema" => Some(Dialect::Draft4),
39 "http://json-schema.org/draft-06/schema" => Some(Dialect::Draft6),
40 "http://json-schema.org/draft-07/schema" => Some(Dialect::Draft7),
41 "https://json-schema.org/draft/2019-09/schema" => Some(Dialect::Draft201909),
42 "https://json-schema.org/draft/2020-12/schema" => Some(Dialect::Draft202012),
43 _ => None,
44 }
45}
46
47pub(crate) fn vocabulary_flag(uri: &str) -> u32 {
49 match uri {
50 "https://json-schema.org/draft/2020-12/vocab/core" | "https://json-schema.org/draft/2019-09/vocab/core" => {
51 vocab::CORE
52 }
53 "https://json-schema.org/draft/2020-12/vocab/applicator"
54 | "https://json-schema.org/draft/2019-09/vocab/applicator" => vocab::APPLICATOR,
55 "https://json-schema.org/draft/2020-12/vocab/validation"
56 | "https://json-schema.org/draft/2019-09/vocab/validation" => vocab::VALIDATION,
57 "https://json-schema.org/draft/2020-12/vocab/meta-data"
58 | "https://json-schema.org/draft/2019-09/vocab/meta-data" => vocab::META_DATA,
59 "https://json-schema.org/draft/2020-12/vocab/format-annotation"
60 | "https://json-schema.org/draft/2019-09/vocab/format" => vocab::FORMAT_ANNOTATION,
61 "https://json-schema.org/draft/2020-12/vocab/format-assertion" => vocab::FORMAT_ASSERTION,
62 "https://json-schema.org/draft/2020-12/vocab/content"
63 | "https://json-schema.org/draft/2019-09/vocab/content" => vocab::CONTENT,
64 "https://json-schema.org/draft/2020-12/vocab/unevaluated" => vocab::UNEVALUATED,
65 _ => vocab::NONE,
66 }
67}
68
69#[derive(Clone, Copy, PartialEq, Eq)]
71pub(crate) enum SubschemaKind {
72 None,
73 Single,
74 SingleOrArray,
75 Array,
76 Map,
77}
78
79pub(crate) fn subschema_kind(keyword: &str, dialect: Dialect, legacy_ref_overrides_siblings: bool) -> SubschemaKind {
81 if keyword == "definitions" || keyword == "$defs" {
82 return SubschemaKind::Map;
83 }
84 if legacy_ref_overrides_siblings {
85 return SubschemaKind::None;
86 }
87 match keyword {
88 "properties" | "patternProperties" | "dependencies" => SubschemaKind::Map,
89 "additionalProperties" | "not" => SubschemaKind::Single,
90 "allOf" | "anyOf" | "oneOf" => SubschemaKind::Array,
91 "items" => {
92 if dialect >= Dialect::Draft202012 {
93 SubschemaKind::Single
94 } else {
95 SubschemaKind::SingleOrArray
96 }
97 }
98 "additionalItems" if dialect <= Dialect::Draft201909 => SubschemaKind::Single,
99 "contains" | "propertyNames" if dialect >= Dialect::Draft6 => SubschemaKind::Single,
100 "if" | "then" | "else" if dialect >= Dialect::Draft7 => SubschemaKind::Single,
101 "unevaluatedProperties" | "unevaluatedItems" | "contentSchema" if dialect >= Dialect::Draft201909 => {
102 SubschemaKind::Single
103 }
104 "dependentSchemas" if dialect >= Dialect::Draft201909 => SubschemaKind::Map,
105 "prefixItems" if dialect >= Dialect::Draft202012 => SubschemaKind::Array,
106 _ => SubschemaKind::None,
107 }
108}