Skip to main content

jsonschema_schema/schema/vocabularies/
applicator.rs

1use indexmap::IndexMap;
2
3use crate::SchemaValue;
4
5/// Applicator vocabulary — composition, conditionals, and object/array subschemas.
6///
7/// See [JSON Schema Core §10](https://json-schema.org/draft/2020-12/json-schema-core#section-10).
8#[derive(
9    Debug,
10    Clone,
11    Default,
12    PartialEq,
13    Eq,
14    serde::Serialize,
15    serde::Deserialize,
16    schemars::JsonSchema,
17    combine_structs::Fields,
18)]
19pub struct ApplicatorVocabulary {
20    /// The `properties` keyword — per-property subschemas.
21    ///
22    /// The value of `"properties"` MUST be an object. Each value of
23    /// this object MUST be a valid JSON Schema.
24    ///
25    /// Validation succeeds if, for each name that appears in both the
26    /// instance and as a name within this keyword's value, the child
27    /// instance for that name successfully validates against the
28    /// corresponding schema.
29    ///
30    /// The annotation result of this keyword is the set of instance
31    /// property names matched by this keyword. This annotation affects
32    /// the behavior of `"additionalProperties"` (in this vocabulary)
33    /// and `"unevaluatedProperties"` in the Unevaluated vocabulary.
34    ///
35    /// Omitting this keyword has the same assertion behavior as an
36    /// empty object.
37    ///
38    /// See [JSON Schema Core §10.3.2.1](https://json-schema.org/draft/2020-12/json-schema-core#section-10.3.2.1).
39    #[serde(default, skip_serializing_if = "IndexMap::is_empty")]
40    #[schemars(extend("default" = {}))]
41    pub properties: IndexMap<String, SchemaValue>,
42
43    /// The `patternProperties` keyword — regex-matched property
44    /// subschemas.
45    ///
46    /// The value of `"patternProperties"` MUST be an object. Each
47    /// property name of this object SHOULD be a valid regular
48    /// expression, according to the ECMA-262 regular expression
49    /// dialect. Each property value of this object MUST be a valid
50    /// JSON Schema.
51    ///
52    /// Validation succeeds if, for each instance name that matches any
53    /// regular expressions that appear as a property name in this
54    /// keyword's value, the child instance for that name successfully
55    /// validates against each schema that corresponds to a matching
56    /// regular expression.
57    ///
58    /// The annotation result of this keyword is the set of instance
59    /// property names matched by this keyword. This annotation affects
60    /// the behavior of `"additionalProperties"` (in this vocabulary)
61    /// and `"unevaluatedProperties"` (in the Unevaluated vocabulary).
62    ///
63    /// Omitting this keyword has the same assertion behavior as an
64    /// empty object.
65    ///
66    /// See [JSON Schema Core §10.3.2.2](https://json-schema.org/draft/2020-12/json-schema-core#section-10.3.2.2).
67    #[serde(
68        default,
69        rename = "patternProperties",
70        skip_serializing_if = "IndexMap::is_empty"
71    )]
72    #[schemars(extend("default" = {}), extend("propertyNames" = { "format": "regex" }))]
73    pub pattern_properties: IndexMap<String, SchemaValue>,
74
75    /// The `additionalProperties` keyword — schema for unmatched
76    /// properties.
77    ///
78    /// The value of `"additionalProperties"` MUST be a valid JSON
79    /// Schema.
80    ///
81    /// The behavior of this keyword depends on the presence and
82    /// annotation results of `"properties"` and `"patternProperties"`
83    /// within the same schema object. Validation with
84    /// `"additionalProperties"` applies only to the child values of
85    /// instance names that do not appear in the annotation results of
86    /// either `"properties"` or `"patternProperties"`.
87    ///
88    /// For all such properties, validation succeeds if the child
89    /// instance validates against the `"additionalProperties"` schema.
90    ///
91    /// The annotation result of this keyword is the set of instance
92    /// property names validated by this keyword's subschema. This
93    /// annotation affects the behavior of `"unevaluatedProperties"` in
94    /// the Unevaluated vocabulary.
95    ///
96    /// Omitting this keyword has the same assertion behavior as an
97    /// empty schema.
98    ///
99    /// See [JSON Schema Core §10.3.2.3](https://json-schema.org/draft/2020-12/json-schema-core#section-10.3.2.3).
100    #[serde(
101        rename = "additionalProperties",
102        skip_serializing_if = "Option::is_none"
103    )]
104    pub additional_properties: Option<Box<SchemaValue>>,
105
106    /// The `propertyNames` keyword — property name schema.
107    ///
108    /// The value of `"propertyNames"` MUST be a valid JSON Schema.
109    ///
110    /// If the instance is an object, this keyword validates if every
111    /// property name in the instance validates against the provided
112    /// schema. Note the property name that the schema is testing will
113    /// always be a string.
114    ///
115    /// Omitting this keyword has the same behavior as an empty schema.
116    ///
117    /// See [JSON Schema Core §10.3.2.4](https://json-schema.org/draft/2020-12/json-schema-core#section-10.3.2.4).
118    #[serde(rename = "propertyNames", skip_serializing_if = "Option::is_none")]
119    pub property_names: Option<Box<SchemaValue>>,
120
121    /// The `dependentSchemas` keyword — conditional subschemas by
122    /// property name.
123    ///
124    /// This keyword specifies subschemas that are evaluated if the
125    /// instance is an object and contains a certain property.
126    ///
127    /// This keyword's value MUST be an object. Each value in the
128    /// object MUST be a valid JSON Schema.
129    ///
130    /// If the object key is a property in the instance, the entire
131    /// instance must validate against the subschema. Its use is
132    /// dependent on the presence of the property.
133    ///
134    /// Omitting this keyword has the same behavior as an empty object.
135    ///
136    /// See [JSON Schema Core §10.2.2.4](https://json-schema.org/draft/2020-12/json-schema-core#section-10.2.2.4).
137    #[serde(
138        default,
139        rename = "dependentSchemas",
140        skip_serializing_if = "IndexMap::is_empty"
141    )]
142    #[schemars(extend("default" = {}))]
143    pub dependent_schemas: IndexMap<String, SchemaValue>,
144
145    /// The `items` keyword — schema for remaining array items.
146    ///
147    /// The value of `"items"` MUST be a valid JSON Schema.
148    ///
149    /// This keyword applies its subschema to all instance elements at
150    /// indexes greater than the length of the `"prefixItems"` array in
151    /// the same schema object, as reported by the annotation result of
152    /// that `"prefixItems"` keyword. If no such annotation result
153    /// exists, `"items"` applies its subschema to all instance array
154    /// elements. Note that the behavior of `"items"` without
155    /// `"prefixItems"` is identical to that of the schema form of
156    /// `"items"` in prior drafts. When `"prefixItems"` is present, the
157    /// behavior of `"items"` is identical to the former
158    /// `"additionalItems"` keyword.
159    ///
160    /// If the `"items"` subschema is applied to any positions within
161    /// the instance array, it produces an annotation result of boolean
162    /// true, indicating that all remaining array elements have been
163    /// evaluated against this keyword's subschema. This annotation
164    /// affects the behavior of `"unevaluatedItems"` in the Unevaluated
165    /// vocabulary.
166    ///
167    /// Omitting this keyword has the same assertion behavior as an
168    /// empty schema.
169    ///
170    /// See [JSON Schema Core §10.3.1.2](https://json-schema.org/draft/2020-12/json-schema-core#section-10.3.1.2).
171    #[serde(skip_serializing_if = "Option::is_none")]
172    pub items: Option<Box<SchemaValue>>,
173
174    /// The `prefixItems` keyword — positional array item schemas.
175    ///
176    /// The value of `"prefixItems"` MUST be a non-empty array of valid
177    /// JSON Schemas.
178    ///
179    /// Validation succeeds if each element of the instance validates
180    /// against the schema at the same position, if any. This keyword
181    /// does not constrain the length of the array. If the array is
182    /// longer than this keyword's value, this keyword validates only
183    /// the prefix of matching length.
184    ///
185    /// This keyword produces an annotation value which is the largest
186    /// index to which this keyword applied a subschema. The value MAY
187    /// be a boolean true if a subschema was applied to every index of
188    /// the instance, such as is produced by the `"items"` keyword.
189    /// This annotation affects the behavior of `"items"` and
190    /// `"unevaluatedItems"`.
191    ///
192    /// Omitting this keyword has the same assertion behavior as an
193    /// empty array.
194    ///
195    /// See [JSON Schema Core §10.3.1.1](https://json-schema.org/draft/2020-12/json-schema-core#section-10.3.1.1).
196    #[serde(rename = "prefixItems", skip_serializing_if = "Option::is_none")]
197    #[schemars(length(min = 1))]
198    pub prefix_items: Option<Vec<SchemaValue>>,
199
200    /// The `contains` keyword — array containment schema.
201    ///
202    /// The value of this keyword MUST be a valid JSON Schema.
203    ///
204    /// An array instance is valid against `"contains"` if at least one
205    /// of its elements is valid against the given schema, except when
206    /// `"minContains"` is present and has a value of 0, in which case
207    /// an array instance MUST be considered valid against the
208    /// `"contains"` keyword, even if none of its elements is valid
209    /// against the given schema.
210    ///
211    /// This keyword produces an annotation value which is an array of
212    /// the indexes to which this keyword validates successfully when
213    /// applying its subschema, in ascending order. The value MAY be a
214    /// boolean `true` if the subschema validates successfully when
215    /// applied to every index of the instance.
216    ///
217    /// The subschema MUST be applied to every array element even after
218    /// the first match has been found, in order to collect annotations
219    /// for use by other keywords. This is to ensure that all possible
220    /// annotations are collected.
221    ///
222    /// See [JSON Schema Core §10.3.1.3](https://json-schema.org/draft/2020-12/json-schema-core#section-10.3.1.3).
223    #[serde(skip_serializing_if = "Option::is_none")]
224    pub contains: Option<Box<SchemaValue>>,
225
226    /// The `allOf` keyword — conjunction of subschemas.
227    ///
228    /// This keyword's value MUST be a non-empty array. Each item of
229    /// the array MUST be a valid JSON Schema.
230    ///
231    /// An instance validates successfully against this keyword if it
232    /// validates successfully against all schemas defined by this
233    /// keyword's value.
234    ///
235    /// See [JSON Schema Core §10.2.1.1](https://json-schema.org/draft/2020-12/json-schema-core#section-10.2.1.1).
236    #[serde(rename = "allOf", skip_serializing_if = "Option::is_none")]
237    #[schemars(length(min = 1))]
238    pub all_of: Option<Vec<SchemaValue>>,
239
240    /// The `anyOf` keyword — disjunction of subschemas.
241    ///
242    /// This keyword's value MUST be a non-empty array. Each item of
243    /// the array MUST be a valid JSON Schema.
244    ///
245    /// An instance validates successfully against this keyword if it
246    /// validates successfully against at least one schema defined by
247    /// this keyword's value. Note that when annotations are being
248    /// collected, all subschemas MUST be examined so that annotations
249    /// are collected from each subschema that validates successfully.
250    ///
251    /// See [JSON Schema Core §10.2.1.2](https://json-schema.org/draft/2020-12/json-schema-core#section-10.2.1.2).
252    #[serde(rename = "anyOf", skip_serializing_if = "Option::is_none")]
253    #[schemars(length(min = 1))]
254    pub any_of: Option<Vec<SchemaValue>>,
255
256    /// The `oneOf` keyword — exclusive disjunction of subschemas.
257    ///
258    /// This keyword's value MUST be a non-empty array. Each item of
259    /// the array MUST be a valid JSON Schema.
260    ///
261    /// An instance validates successfully against this keyword if it
262    /// validates successfully against exactly one schema defined by
263    /// this keyword's value.
264    ///
265    /// See [JSON Schema Core §10.2.1.3](https://json-schema.org/draft/2020-12/json-schema-core#section-10.2.1.3).
266    #[serde(rename = "oneOf", skip_serializing_if = "Option::is_none")]
267    #[schemars(length(min = 1))]
268    pub one_of: Option<Vec<SchemaValue>>,
269
270    /// The `not` keyword — negation.
271    ///
272    /// This keyword's value MUST be a valid JSON Schema.
273    ///
274    /// An instance is valid against this keyword if it fails to
275    /// validate successfully against the schema defined by this
276    /// keyword.
277    ///
278    /// See [JSON Schema Core §10.2.1.4](https://json-schema.org/draft/2020-12/json-schema-core#section-10.2.1.4).
279    #[serde(skip_serializing_if = "Option::is_none")]
280    pub not: Option<Box<SchemaValue>>,
281
282    /// The `if` keyword — conditional guard.
283    ///
284    /// This keyword's value MUST be a valid JSON Schema.
285    ///
286    /// This validation outcome of this keyword's subschema has no
287    /// direct effect on the overall validation result. Rather, it
288    /// controls which of the `"then"` or `"else"` keywords are
289    /// evaluated.
290    ///
291    /// Instances that successfully validate against this keyword's
292    /// subschema MUST also be valid against the subschema value of the
293    /// `"then"` keyword, if present.
294    ///
295    /// Instances that fail to validate against this keyword's
296    /// subschema MUST also be valid against the subschema value of the
297    /// `"else"` keyword, if present.
298    ///
299    /// If annotations are being collected, they are collected from
300    /// this keyword's subschema in the usual way, including when the
301    /// keyword is present without either `"then"` or `"else"`.
302    ///
303    /// See [JSON Schema Core §10.2.2.1](https://json-schema.org/draft/2020-12/json-schema-core#section-10.2.2.1).
304    #[serde(rename = "if", skip_serializing_if = "Option::is_none")]
305    pub if_: Option<Box<SchemaValue>>,
306
307    /// The `then` keyword — consequent subschema.
308    ///
309    /// This keyword's value MUST be a valid JSON Schema.
310    ///
311    /// When `"if"` is present, and the instance successfully validates
312    /// against its subschema, then validation succeeds against this
313    /// keyword if the instance also successfully validates against
314    /// this keyword's subschema.
315    ///
316    /// This keyword has no effect when `"if"` is absent, or when the
317    /// instance fails to validate against its subschema.
318    /// Implementations MUST NOT evaluate the instance against this
319    /// keyword, for either validation or annotation collection
320    /// purposes, in such cases.
321    ///
322    /// See [JSON Schema Core §10.2.2.2](https://json-schema.org/draft/2020-12/json-schema-core#section-10.2.2.2).
323    #[serde(rename = "then", skip_serializing_if = "Option::is_none")]
324    pub then_: Option<Box<SchemaValue>>,
325
326    /// The `else` keyword — alternative subschema.
327    ///
328    /// This keyword's value MUST be a valid JSON Schema.
329    ///
330    /// When `"if"` is present, and the instance fails to validate
331    /// against its subschema, then validation succeeds against this
332    /// keyword if the instance successfully validates against this
333    /// keyword's subschema.
334    ///
335    /// This keyword has no effect when `"if"` is absent, or when the
336    /// instance successfully validates against its subschema.
337    /// Implementations MUST NOT evaluate the instance against this
338    /// keyword, for either validation or annotation collection
339    /// purposes, in such cases.
340    ///
341    /// See [JSON Schema Core §10.2.2.3](https://json-schema.org/draft/2020-12/json-schema-core#section-10.2.2.3).
342    #[serde(rename = "else", skip_serializing_if = "Option::is_none")]
343    pub else_: Option<Box<SchemaValue>>,
344}