vector_config_common/schema/json_schema.rs
1use serde::{Deserialize, Serialize};
2use serde_json::Value;
3use std::{iter, ops::Deref};
4
5use super::{Map, Set, DEFINITIONS_PREFIX};
6
7/// A JSON Schema.
8#[allow(clippy::large_enum_variant)]
9#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
10#[serde(untagged)]
11pub enum Schema {
12 /// A trivial boolean JSON Schema.
13 ///
14 /// The schema `true` matches everything (always passes validation), whereas the schema `false`
15 /// matches nothing (always fails validation).
16 Bool(bool),
17
18 /// A JSON Schema object.
19 Object(SchemaObject),
20}
21
22impl Schema {
23 /// Creates a new `$ref` schema.
24 ///
25 /// The given reference string should be a URI reference. This will usually be a JSON Pointer
26 /// in [URI Fragment representation](https://tools.ietf.org/html/rfc6901#section-6).
27 pub fn new_ref(reference: String) -> Self {
28 SchemaObject::new_ref(reference).into()
29 }
30
31 /// Returns `true` if `self` is a `$ref` schema.
32 ///
33 /// If `self` is a [`SchemaObject`] with `Some`
34 /// [`reference`](struct.SchemaObject.html#structfield.reference) set, this returns `true`.
35 /// Otherwise, returns `false`.
36 pub fn is_ref(&self) -> bool {
37 match self {
38 Schema::Object(o) => o.is_ref(),
39 _ => false,
40 }
41 }
42
43 /// Gets a reference to the inner schema object if this schema is a JSON Schema object.
44 ///
45 /// Otherwise, `None` is returned.
46 pub fn as_object(&self) -> Option<&SchemaObject> {
47 match self {
48 Schema::Object(schema) => Some(schema),
49 _ => None,
50 }
51 }
52
53 /// Gets a mutable reference to the inner schema object if this schema is a JSON Schema object.
54 ///
55 /// Otherwise, `None` is returned.
56 pub fn as_object_mut(&mut self) -> Option<&mut SchemaObject> {
57 match self {
58 Schema::Object(schema) => Some(schema),
59 _ => None,
60 }
61 }
62
63 /// Converts the given schema (if it is a boolean schema) into an equivalent schema object.
64 ///
65 /// If the given schema is already a schema object, this has no effect.
66 pub fn into_object(self) -> SchemaObject {
67 match self {
68 Schema::Object(o) => o,
69 Schema::Bool(true) => SchemaObject::default(),
70 Schema::Bool(false) => SchemaObject {
71 subschemas: Some(Box::new(SubschemaValidation {
72 not: Some(Schema::Object(Default::default()).into()),
73 ..Default::default()
74 })),
75 ..Default::default()
76 },
77 }
78 }
79}
80
81impl From<SchemaObject> for Schema {
82 fn from(o: SchemaObject) -> Self {
83 Schema::Object(o)
84 }
85}
86
87impl From<bool> for Schema {
88 fn from(b: bool) -> Self {
89 Schema::Bool(b)
90 }
91}
92
93/// The root object of a JSON Schema document.
94#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
95#[serde(rename_all = "camelCase", default)]
96pub struct RootSchema {
97 /// The `$schema` keyword.
98 ///
99 /// See [JSON Schema 8.1.1. The "$schema" Keyword](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-8.1.1).
100 #[serde(rename = "$schema", skip_serializing_if = "Option::is_none")]
101 pub meta_schema: Option<String>,
102
103 /// The root schema itself.
104 #[serde(flatten)]
105 pub schema: SchemaObject,
106
107 /// The `definitions` keyword.
108 ///
109 /// In JSON Schema draft 2019-09 this was replaced by $defs, but in Schemars this is still
110 /// serialized as `definitions` for backward-compatibility.
111 ///
112 /// See [JSON Schema 8.2.5. Schema Re-Use With "$defs"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-8.2.5),
113 /// and [JSON Schema (draft 07) 9. Schema Re-Use With "definitions"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-01#section-9).
114 #[serde(alias = "$defs", skip_serializing_if = "Map::is_empty")]
115 pub definitions: Map<String, Schema>,
116}
117
118/// A JSON Schema object.
119#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
120#[serde(rename_all = "camelCase", default)]
121pub struct SchemaObject {
122 /// Properties which annotate the [`SchemaObject`] which typically have no effect when an object is being validated against the schema.
123 #[serde(flatten, deserialize_with = "skip_if_default")]
124 pub metadata: Option<Box<Metadata>>,
125
126 /// The `type` keyword.
127 ///
128 /// See [JSON Schema Validation 6.1.1. "type"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.1.1)
129 /// and [JSON Schema 4.2.1. Instance Data Model](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-4.2.1).
130 #[serde(rename = "type", skip_serializing_if = "Option::is_none")]
131 pub instance_type: Option<SingleOrVec<InstanceType>>,
132
133 /// The `format` keyword.
134 ///
135 /// See [JSON Schema Validation 7. A Vocabulary for Semantic Content With "format"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-7).
136 #[serde(skip_serializing_if = "Option::is_none")]
137 pub format: Option<String>,
138
139 /// The `enum` keyword.
140 ///
141 /// See [JSON Schema Validation 6.1.2. "enum"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.1.2)
142 #[serde(rename = "enum", skip_serializing_if = "Option::is_none")]
143 pub enum_values: Option<Vec<Value>>,
144
145 /// The `const` keyword.
146 ///
147 /// See [JSON Schema Validation 6.1.3. "const"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.1.3)
148 #[serde(
149 rename = "const",
150 skip_serializing_if = "Option::is_none",
151 deserialize_with = "allow_null"
152 )]
153 pub const_value: Option<Value>,
154
155 /// Properties of the [`SchemaObject`] which define validation assertions in terms of other schemas.
156 #[serde(flatten, deserialize_with = "skip_if_default")]
157 pub subschemas: Option<Box<SubschemaValidation>>,
158
159 /// Properties of the [`SchemaObject`] which define validation assertions for numbers.
160 #[serde(flatten, deserialize_with = "skip_if_default")]
161 pub number: Option<Box<NumberValidation>>,
162
163 /// Properties of the [`SchemaObject`] which define validation assertions for strings.
164 #[serde(flatten, deserialize_with = "skip_if_default")]
165 pub string: Option<Box<StringValidation>>,
166
167 /// Properties of the [`SchemaObject`] which define validation assertions for arrays.
168 #[serde(flatten, deserialize_with = "skip_if_default")]
169 pub array: Option<Box<ArrayValidation>>,
170
171 /// Properties of the [`SchemaObject`] which define validation assertions for objects.
172 #[serde(flatten, deserialize_with = "skip_if_default")]
173 pub object: Option<Box<ObjectValidation>>,
174
175 /// The `$ref` keyword.
176 ///
177 /// See [JSON Schema 8.2.4.1. Direct References with "$ref"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-8.2.4.1).
178 #[serde(rename = "$ref", skip_serializing_if = "Option::is_none")]
179 pub reference: Option<String>,
180
181 /// Arbitrary extra properties which are not part of the JSON Schema specification, or which `schemars` does not support.
182 #[serde(flatten)]
183 pub extensions: Map<String, Value>,
184}
185
186// Deserializing "null" to `Option<Value>` directly results in `None`,
187// this function instead makes it deserialize to `Some(Value::Null)`.
188fn allow_null<'de, D>(de: D) -> Result<Option<Value>, D::Error>
189where
190 D: serde::Deserializer<'de>,
191{
192 Value::deserialize(de).map(Option::Some)
193}
194
195fn skip_if_default<'de, D, T>(deserializer: D) -> Result<Option<Box<T>>, D::Error>
196where
197 D: serde::Deserializer<'de>,
198 T: Deserialize<'de> + Default + PartialEq,
199{
200 let value = T::deserialize(deserializer)?;
201 Ok((value != T::default()).then(|| Box::new(value)))
202}
203
204macro_rules! get_or_insert_default_fn {
205 ($name:ident, $ret:ty) => {
206 get_or_insert_default_fn!(
207 concat!(
208 "Returns a mutable reference to this schema's [`",
209 stringify!($ret),
210 "`](#structfield.",
211 stringify!($name),
212 "), creating it if it was `None`."
213 ),
214 $name,
215 $ret
216 );
217 };
218 ($doc:expr, $name:ident, $ret:ty) => {
219 #[doc = $doc]
220 pub fn $name(&mut self) -> &mut $ret {
221 self.$name.get_or_insert_with(Default::default)
222 }
223 };
224}
225
226impl SchemaObject {
227 /// Creates a new `$ref` schema.
228 ///
229 /// The given reference string should be a URI reference. This will usually be a JSON Pointer
230 /// in [URI Fragment representation](https://tools.ietf.org/html/rfc6901#section-6).
231 pub fn new_ref(reference: String) -> Self {
232 SchemaObject {
233 reference: Some(reference),
234 ..Default::default()
235 }
236 }
237
238 /// Returns `true` if `self` is a `$ref` schema.
239 ///
240 /// If `self` has `Some` [`reference`](struct.SchemaObject.html#structfield.reference) set, this returns `true`.
241 /// Otherwise, returns `false`.
242 pub fn is_ref(&self) -> bool {
243 self.reference.is_some()
244 }
245
246 /// Returns `true` if `self` accepts values of the given type, according to the [`Self::instance_type`] field.
247 ///
248 /// This is a basic check that always returns `true` if no `instance_type` is specified on the schema,
249 /// and does not check any subschemas. Because of this, both `{}` and `{"not": {}}` accept any type according
250 /// to this method.
251 pub fn has_type(&self, ty: InstanceType) -> bool {
252 self.instance_type.as_ref().is_none_or(|x| x.contains(&ty))
253 }
254
255 get_or_insert_default_fn!(metadata, Metadata);
256 get_or_insert_default_fn!(subschemas, SubschemaValidation);
257 get_or_insert_default_fn!(number, NumberValidation);
258 get_or_insert_default_fn!(string, StringValidation);
259 get_or_insert_default_fn!(array, ArrayValidation);
260 get_or_insert_default_fn!(object, ObjectValidation);
261}
262
263impl From<Schema> for SchemaObject {
264 fn from(schema: Schema) -> Self {
265 schema.into_object()
266 }
267}
268
269/// Properties which annotate a [`SchemaObject`] which typically have no effect when an object is being validated against the schema.
270#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
271#[serde(rename_all = "camelCase", default)]
272pub struct Metadata {
273 /// The `$id` keyword.
274 ///
275 /// See [JSON Schema 8.2.2. The "$id" Keyword](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-8.2.2).
276 #[serde(rename = "$id", skip_serializing_if = "Option::is_none")]
277 pub id: Option<String>,
278
279 /// The `title` keyword.
280 ///
281 /// See [JSON Schema Validation 9.1. "title" and "description"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.1).
282 #[serde(skip_serializing_if = "Option::is_none")]
283 pub title: Option<String>,
284
285 /// The `description` keyword.
286 ///
287 /// See [JSON Schema Validation 9.1. "title" and "description"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.1).
288 #[serde(skip_serializing_if = "Option::is_none")]
289 pub description: Option<String>,
290
291 /// The `default` keyword.
292 ///
293 /// See [JSON Schema Validation 9.2. "default"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.2).
294 #[serde(
295 skip_serializing_if = "Option::is_none",
296 deserialize_with = "allow_null"
297 )]
298 pub default: Option<Value>,
299
300 /// The `deprecated` keyword.
301 ///
302 /// See [JSON Schema Validation 9.3. "deprecated"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.3).
303 #[serde(skip_serializing_if = "is_false")]
304 pub deprecated: bool,
305
306 /// The `readOnly` keyword.
307 ///
308 /// See [JSON Schema Validation 9.4. "readOnly" and "writeOnly"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.4).
309 #[serde(skip_serializing_if = "is_false")]
310 pub read_only: bool,
311
312 /// The `writeOnly` keyword.
313 ///
314 /// See [JSON Schema Validation 9.4. "readOnly" and "writeOnly"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.4).
315 #[serde(skip_serializing_if = "is_false")]
316 pub write_only: bool,
317
318 /// The `examples` keyword.
319 ///
320 /// See [JSON Schema Validation 9.5. "examples"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-9.5).
321 #[serde(skip_serializing_if = "Vec::is_empty")]
322 pub examples: Vec<Value>,
323}
324
325#[allow(clippy::trivially_copy_pass_by_ref)]
326fn is_false(b: &bool) -> bool {
327 !b
328}
329
330/// Properties of a [`SchemaObject`] which define validation assertions in terms of other schemas.
331#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
332#[serde(rename_all = "camelCase", default)]
333pub struct SubschemaValidation {
334 /// The `allOf` keyword.
335 ///
336 /// See [JSON Schema 9.2.1.1. "allOf"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.1.1).
337 #[serde(skip_serializing_if = "Option::is_none")]
338 pub all_of: Option<Vec<Schema>>,
339
340 /// The `anyOf` keyword.
341 ///
342 /// See [JSON Schema 9.2.1.2. "anyOf"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.1.2).
343 #[serde(skip_serializing_if = "Option::is_none")]
344 pub any_of: Option<Vec<Schema>>,
345
346 /// The `oneOf` keyword.
347 ///
348 /// See [JSON Schema 9.2.1.3. "oneOf"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.1.3).
349 #[serde(skip_serializing_if = "Option::is_none")]
350 pub one_of: Option<Vec<Schema>>,
351
352 /// The `not` keyword.
353 ///
354 /// See [JSON Schema 9.2.1.4. "not"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.1.4).
355 #[serde(skip_serializing_if = "Option::is_none")]
356 pub not: Option<Box<Schema>>,
357
358 /// The `if` keyword.
359 ///
360 /// See [JSON Schema 9.2.2.1. "if"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.2.1).
361 #[serde(rename = "if", skip_serializing_if = "Option::is_none")]
362 pub if_schema: Option<Box<Schema>>,
363
364 /// The `then` keyword.
365 ///
366 /// See [JSON Schema 9.2.2.2. "then"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.2.2).
367 #[serde(rename = "then", skip_serializing_if = "Option::is_none")]
368 pub then_schema: Option<Box<Schema>>,
369
370 /// The `else` keyword.
371 ///
372 /// See [JSON Schema 9.2.2.3. "else"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.2.2.3).
373 #[serde(rename = "else", skip_serializing_if = "Option::is_none")]
374 pub else_schema: Option<Box<Schema>>,
375}
376
377/// Properties of a [`SchemaObject`] which define validation assertions for numbers.
378#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
379#[serde(rename_all = "camelCase", default)]
380pub struct NumberValidation {
381 /// The `multipleOf` keyword.
382 ///
383 /// See [JSON Schema Validation 6.2.1. "multipleOf"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.2.1).
384 #[serde(skip_serializing_if = "Option::is_none")]
385 pub multiple_of: Option<f64>,
386
387 /// The `maximum` keyword.
388 ///
389 /// See [JSON Schema Validation 6.2.2. "maximum"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.2.2).
390 #[serde(skip_serializing_if = "Option::is_none")]
391 pub maximum: Option<f64>,
392
393 /// The `exclusiveMaximum` keyword.
394 ///
395 /// See [JSON Schema Validation 6.2.3. "exclusiveMaximum"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.2.3).
396 #[serde(skip_serializing_if = "Option::is_none")]
397 pub exclusive_maximum: Option<f64>,
398
399 /// The `minimum` keyword.
400 ///
401 /// See [JSON Schema Validation 6.2.4. "minimum"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.2.4).
402 #[serde(skip_serializing_if = "Option::is_none")]
403 pub minimum: Option<f64>,
404
405 /// The `exclusiveMinimum` keyword.
406 ///
407 /// See [JSON Schema Validation 6.2.5. "exclusiveMinimum"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.2.5).
408 #[serde(skip_serializing_if = "Option::is_none")]
409 pub exclusive_minimum: Option<f64>,
410}
411
412/// Properties of a [`SchemaObject`] which define validation assertions for strings.
413#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
414#[serde(rename_all = "camelCase", default)]
415pub struct StringValidation {
416 /// The `maxLength` keyword.
417 ///
418 /// See [JSON Schema Validation 6.3.1. "maxLength"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.3.1).
419 #[serde(skip_serializing_if = "Option::is_none")]
420 pub max_length: Option<u32>,
421
422 /// The `minLength` keyword.
423 ///
424 /// See [JSON Schema Validation 6.3.2. "minLength"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.3.2).
425 #[serde(skip_serializing_if = "Option::is_none")]
426 pub min_length: Option<u32>,
427
428 /// The `pattern` keyword.
429 ///
430 /// See [JSON Schema Validation 6.3.3. "pattern"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.3.3).
431 #[serde(skip_serializing_if = "Option::is_none")]
432 pub pattern: Option<String>,
433}
434
435/// Properties of a [`SchemaObject`] which define validation assertions for arrays.
436#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
437#[serde(rename_all = "camelCase", default)]
438pub struct ArrayValidation {
439 /// The `items` keyword.
440 ///
441 /// See [JSON Schema 9.3.1.1. "items"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.1.1).
442 #[serde(skip_serializing_if = "Option::is_none")]
443 pub items: Option<SingleOrVec<Schema>>,
444
445 /// The `additionalItems` keyword.
446 ///
447 /// See [JSON Schema 9.3.1.2. "additionalItems"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.1.2).
448 #[serde(skip_serializing_if = "Option::is_none")]
449 pub additional_items: Option<Box<Schema>>,
450
451 /// The `unevaluatedItems` keyword.
452 ///
453 /// See [JSON Schema 9.3.1.3. "unevaluatedItems"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.1.3).
454 #[serde(skip_serializing_if = "Option::is_none")]
455 pub unevaluated_items: Option<Box<Schema>>,
456
457 /// The `maxItems` keyword.
458 ///
459 /// See [JSON Schema Validation 6.4.1. "maxItems"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.4.1).
460 #[serde(skip_serializing_if = "Option::is_none")]
461 pub max_items: Option<u32>,
462
463 /// The `minItems` keyword.
464 ///
465 /// See [JSON Schema Validation 6.4.2. "minItems"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.4.2).
466 #[serde(skip_serializing_if = "Option::is_none")]
467 pub min_items: Option<u32>,
468
469 /// The `uniqueItems` keyword.
470 ///
471 /// See [JSON Schema Validation 6.4.3. "uniqueItems"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.4.3).
472 #[serde(skip_serializing_if = "Option::is_none")]
473 pub unique_items: Option<bool>,
474
475 /// The `contains` keyword.
476 ///
477 /// See [JSON Schema 9.3.1.4. "contains"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.1.4).
478 #[serde(skip_serializing_if = "Option::is_none")]
479 pub contains: Option<Box<Schema>>,
480}
481
482/// Properties of a [`SchemaObject`] which define validation assertions for objects.
483#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
484#[serde(rename_all = "camelCase", default)]
485pub struct ObjectValidation {
486 /// The `maxProperties` keyword.
487 ///
488 /// See [JSON Schema Validation 6.5.1. "maxProperties"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.5.1).
489 #[serde(skip_serializing_if = "Option::is_none")]
490 pub max_properties: Option<u32>,
491
492 /// The `minProperties` keyword.
493 ///
494 /// See [JSON Schema Validation 6.5.2. "minProperties"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.5.2).
495 #[serde(skip_serializing_if = "Option::is_none")]
496 pub min_properties: Option<u32>,
497
498 /// The `required` keyword.
499 ///
500 /// See [JSON Schema Validation 6.5.3. "required"](https://tools.ietf.org/html/draft-handrews-json-schema-validation-02#section-6.5.3).
501 #[serde(skip_serializing_if = "Set::is_empty")]
502 pub required: Set<String>,
503
504 /// The `properties` keyword.
505 ///
506 /// See [JSON Schema 9.3.2.1. "properties"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.2.1).
507 #[serde(skip_serializing_if = "Map::is_empty")]
508 pub properties: Map<String, Schema>,
509
510 /// The `patternProperties` keyword.
511 ///
512 /// See [JSON Schema 9.3.2.2. "patternProperties"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.2.2).
513 #[serde(skip_serializing_if = "Map::is_empty")]
514 pub pattern_properties: Map<String, Schema>,
515
516 /// The `additionalProperties` keyword.
517 ///
518 /// See [JSON Schema 9.3.2.3. "additionalProperties"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.2.3).
519 #[serde(skip_serializing_if = "is_none_or_default_true")]
520 pub additional_properties: Option<Box<Schema>>,
521
522 /// The `unevaluatedProperties` keyword.
523 ///
524 /// See [JSON Schema 9.3.2.4. "unevaluatedProperties"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.2.4).
525 #[serde(skip_serializing_if = "is_none_or_default_true")]
526 pub unevaluated_properties: Option<Box<Schema>>,
527
528 /// The `propertyNames` keyword.
529 ///
530 /// See [JSON Schema 9.3.2.5. "propertyNames"](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-9.3.2.5).
531 #[serde(skip_serializing_if = "Option::is_none")]
532 pub property_names: Option<Box<Schema>>,
533}
534
535/// The possible types of values in JSON Schema documents.
536///
537/// See [JSON Schema 4.2.1. Instance Data Model](https://tools.ietf.org/html/draft-handrews-json-schema-02#section-4.2.1).
538#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
539#[serde(rename_all = "camelCase")]
540pub enum InstanceType {
541 Null,
542 Boolean,
543 Object,
544 Array,
545 Number,
546 String,
547 Integer,
548}
549
550/// A type which can be serialized as a single item, or multiple items.
551///
552/// In some contexts, a `Single` may be semantically distinct from a `Vec` containing only item.
553#[derive(Clone, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)]
554#[serde(untagged)]
555pub enum SingleOrVec<T> {
556 Single(Box<T>),
557 Vec(Vec<T>),
558}
559
560impl<T: Clone> Extend<T> for SingleOrVec<T> {
561 fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
562 match self {
563 Self::Single(item) => {
564 *self = Self::Vec(iter::once(*item.clone()).chain(iter).collect());
565 }
566 Self::Vec(items) => items.extend(iter),
567 }
568 }
569}
570
571impl<'a, T> IntoIterator for &'a SingleOrVec<T> {
572 type Item = &'a T;
573
574 type IntoIter = std::slice::Iter<'a, T>;
575
576 fn into_iter(self) -> Self::IntoIter {
577 match self {
578 SingleOrVec::Single(item) => std::slice::from_ref(item.as_ref()).iter(),
579 SingleOrVec::Vec(items) => items.as_slice().iter(),
580 }
581 }
582}
583
584impl<T> From<T> for SingleOrVec<T> {
585 fn from(single: T) -> Self {
586 SingleOrVec::Single(Box::new(single))
587 }
588}
589
590impl<T> From<Vec<T>> for SingleOrVec<T> {
591 fn from(vec: Vec<T>) -> Self {
592 SingleOrVec::Vec(vec)
593 }
594}
595
596impl<T: PartialEq> SingleOrVec<T> {
597 /// Returns `true` if `self` is either a `Single` equal to `x`, or a `Vec` containing `x`.
598 pub fn contains(&self, x: &T) -> bool {
599 match self {
600 SingleOrVec::Single(s) => s.deref() == x,
601 SingleOrVec::Vec(v) => v.contains(x),
602 }
603 }
604}
605
606fn is_none_or_default_true(field: &Option<Box<Schema>>) -> bool {
607 match field {
608 None => true,
609 Some(value) => matches!(value.as_ref(), Schema::Bool(true)),
610 }
611}
612
613pub fn get_cleaned_schema_reference(schema_ref: &str) -> &str {
614 if let Some(cleaned) = schema_ref.strip_prefix(DEFINITIONS_PREFIX) {
615 cleaned
616 } else {
617 panic!(
618 "Tried to clean schema reference that does not start with the definition prefix: {schema_ref}"
619 );
620 }
621}