Skip to content

Commit

Permalink
Support draft 2020-12
Browse files Browse the repository at this point in the history
  • Loading branch information
GREsau committed May 19, 2024
1 parent 95475ad commit 961a0de
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 21 deletions.
23 changes: 18 additions & 5 deletions schemars/src/gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use std::{any::Any, collections::HashSet, fmt::Debug};

/// Settings to customize how Schemas are generated.
///
/// The default settings currently conform to [JSON Schema Draft 7](https://json-schema.org/specification-links.html#draft-7), but this is liable to change in a future version of Schemars if support for other JSON Schema versions is added.
/// The default settings currently conform to [JSON Schema Draft 7](https://json-schema.org/specification-links#draft-7), but this is liable to change in a future version of Schemars if support for other JSON Schema versions is added.
/// If you require your generated schemas to conform to draft 7, consider using the [`draft07`](#method.draft07) method.
#[derive(Debug, Clone)]
#[non_exhaustive]
Expand All @@ -29,7 +29,7 @@ pub struct SchemaSettings {
///
/// Defaults to `false`.
pub option_nullable: bool,
/// If `true`, schemas for [`Option<T>`](Option) will have `null` added to their [`type`](../schema/struct.SchemaObject.html#structfield.instance_type).
/// If `true`, schemas for [`Option<T>`](Option) will have `null` added to their [`type`](../schema/struct.SchemaObject#structfield.instance_type).
///
/// Defaults to `true`.
pub option_add_null_type: bool,
Expand Down Expand Up @@ -58,25 +58,37 @@ impl Default for SchemaSettings {
}

impl SchemaSettings {
/// Creates `SchemaSettings` that conform to [JSON Schema Draft 7](https://json-schema.org/specification-links.html#draft-7).
/// Creates `SchemaSettings` that conform to [JSON Schema Draft 7](https://json-schema.org/specification-links#draft-7).
pub fn draft07() -> SchemaSettings {
SchemaSettings {
option_nullable: false,
option_add_null_type: true,
definitions_path: "#/definitions/".to_owned(),
meta_schema: Some("http://json-schema.org/draft-07/schema#".to_owned()),
visitors: vec![Box::new(RemoveRefSiblings)],
visitors: vec![Box::new(RemoveRefSiblings), Box::new(ReplacePrefixItems)],
inline_subschemas: false,
}
}

/// Creates `SchemaSettings` that conform to [JSON Schema 2019-09](https://json-schema.org/specification-links.html#2019-09-formerly-known-as-draft-8).
/// Creates `SchemaSettings` that conform to [JSON Schema 2019-09](https://json-schema.org/specification-links#draft-2019-09-(formerly-known-as-draft-8)).
pub fn draft2019_09() -> SchemaSettings {
SchemaSettings {
option_nullable: false,
option_add_null_type: true,
definitions_path: "#/$defs/".to_owned(),
meta_schema: Some("https://json-schema.org/draft/2019-09/schema".to_owned()),
visitors: vec![Box::new(ReplacePrefixItems)],
inline_subschemas: false,
}
}

/// Creates `SchemaSettings` that conform to [JSON Schema 2020-12](https://json-schema.org/specification-links#2020-12).
pub fn draft2020_12() -> SchemaSettings {
SchemaSettings {
option_nullable: false,
option_add_null_type: true,
definitions_path: "#/$defs/".to_owned(),
meta_schema: Some("https://json-schema.org/draft/2020-12/schema".to_owned()),
visitors: Vec::new(),
inline_subschemas: false,
}
Expand All @@ -99,6 +111,7 @@ impl SchemaSettings {
}),
Box::new(SetSingleExample),
Box::new(ReplaceConstValue),
Box::new(ReplacePrefixItems),
],
inline_subschemas: false,
}
Expand Down
2 changes: 1 addition & 1 deletion schemars/src/ser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ impl serde::ser::SerializeTuple for SerializeTuple<'_> {
let len = self.items.len();
let mut schema = json_schema!({
"type": "array",
"items": self.items,
"prefixItems": self.items,
"maxItems": len,
"minItems": len,
});
Expand Down
36 changes: 22 additions & 14 deletions schemars/src/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,15 @@ pub fn visit_schema<V: Visitor + ?Sized>(v: &mut V, schema: &mut Schema) {
| "if"
| "then"
| "else"
| "additionalItems"
| "contains"
| "additionalProperties"
| "propertyNames" => {
| "propertyNames"
| "items" => {
if let Ok(subschema) = value.try_into() {
v.visit_schema(subschema)
}
}
"allOf" | "anyOf" | "oneOf" => {
"allOf" | "anyOf" | "oneOf" | "prefixItems" => {
if let Some(array) = value.as_array_mut() {
for value in array {
if let Ok(subschema) = value.try_into() {
Expand All @@ -67,17 +67,6 @@ pub fn visit_schema<V: Visitor + ?Sized>(v: &mut V, schema: &mut Schema) {
}
}
}
"items" => {
if let Some(array) = value.as_array_mut() {
for value in array {
if let Ok(subschema) = value.try_into() {
v.visit_schema(subschema)
}
}
} else if let Ok(subschema) = value.try_into() {
v.visit_schema(subschema)
}
}
"properties" | "patternProperties" => {
if let Some(obj) = value.as_object_mut() {
for value in obj.values_mut() {
Expand Down Expand Up @@ -187,3 +176,22 @@ impl Visitor for ReplaceConstValue {
}
}
}

#[derive(Debug, Clone)]
pub struct ReplacePrefixItems;

impl Visitor for ReplacePrefixItems {
fn visit_schema(&mut self, schema: &mut Schema) {
visit_schema(self, schema);

if let Some(obj) = schema.as_object_mut() {
if let Some(prefix_items) = obj.remove("prefixItems") {
let previous_items = obj.insert("items".to_owned(), prefix_items);

if let Some(previous_items) = previous_items {
obj.insert("additionalItems".to_owned(), previous_items);
}
}
}
}
}
2 changes: 1 addition & 1 deletion schemars_derive/src/schema_exprs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,7 @@ fn expr_for_tuple_struct(fields: &[Field]) -> TokenStream {
quote! {
schemars::json_schema!({
"type": "array",
"items": [#((#fields)),*],
"prefixItems": [#((#fields)),*],
"minItems": #len,
"maxItems": #len,
})
Expand Down

0 comments on commit 961a0de

Please sign in to comment.