Support JSON Schema draft 2020-12 and use it by default (#294)

This commit is contained in:
Graham Esau 2024-05-19 20:49:45 +01:00 committed by GitHub
parent 95475ad1b4
commit 3aa0e7fa3c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
88 changed files with 369 additions and 210 deletions

View file

@ -18,18 +18,18 @@ 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.
/// If you require your generated schemas to conform to draft 7, consider using the [`draft07`](#method.draft07) method.
/// The default settings currently conform to [JSON Schema 2020-12](https://json-schema.org/specification-links#2020-12), but this is liable to change in a future version of Schemars if support for other JSON Schema versions is added.
/// If you rely on generated schemas conforming to draft 2020-12, consider using the [`SchemaSettings::draft2020_12()`] method.
#[derive(Debug, Clone)]
#[non_exhaustive]
pub struct SchemaSettings {
/// If `true`, schemas for [`Option<T>`](Option) will include a `nullable` property.
/// If `true`, schemas for [`Option<T>`] will include a `nullable` property.
///
/// This is not part of the JSON Schema spec, but is used in Swagger/OpenAPI schemas.
///
/// 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>`] will have `null` added to their `type` property.
///
/// Defaults to `true`.
pub option_add_null_type: bool,
@ -39,9 +39,9 @@ pub struct SchemaSettings {
pub definitions_path: String,
/// The URI of the meta-schema describing the structure of the generated schemas.
///
/// Defaults to `"http://json-schema.org/draft-07/schema#"`.
/// Defaults to `"https://json-schema.org/draft/2020-12/schema"`.
pub meta_schema: Option<String>,
/// A list of visitors that get applied to all generated root schemas.
/// A list of visitors that get applied to all generated schemas.
pub visitors: Vec<Box<dyn GenVisitor>>,
/// Inline all subschemas instead of using references.
///
@ -53,30 +53,42 @@ pub struct SchemaSettings {
impl Default for SchemaSettings {
fn default() -> SchemaSettings {
SchemaSettings::draft07()
SchemaSettings::draft2020_12()
}
}
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,
}
@ -99,6 +111,7 @@ impl SchemaSettings {
}),
Box::new(SetSingleExample),
Box::new(ReplaceConstValue),
Box::new(ReplacePrefixItems),
],
inline_subschemas: false,
}

View file

@ -25,7 +25,7 @@ macro_rules! tuple_impls {
fn json_schema(gen: &mut SchemaGenerator) -> Schema {
json_schema!({
"type": "array",
"items": [
"prefixItems": [
$(gen.subschema_for::<$name>()),+
],
"minItems": $len,

View file

@ -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,
});

View file

@ -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() {
@ -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() {
@ -126,7 +115,7 @@ impl Visitor for ReplaceBoolSchemas {
/// This visitor will restructure JSON Schema objects so that the `$ref` property will never appear alongside any other properties.
///
/// This is useful for dialects of JSON Schema (e.g. Draft 7) that do not support other properties alongside `$ref`.
/// This is useful for versions of JSON Schema (e.g. Draft 7) that do not support other properties alongside `$ref`.
#[derive(Debug, Clone)]
pub struct RemoveRefSiblings;
@ -187,3 +176,27 @@ impl Visitor for ReplaceConstValue {
}
}
}
/// This visitor will rename the `prefixItems` schema property to `items`.
///
/// If the schema contains both `prefixItems` and `items`, then this additionally renames `items` to `additionalItems`.
///
/// This is useful for versions of JSON Schema (e.g. Draft 7) that do not support the `prefixItems` property.
#[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);
}
}
}
}
}

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Array_up_to_size_16_of_int32",
"type": "array",
"items": {

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "string",
"type": "string"
}

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Decimal",
"type": "string",
"pattern": "^-?[0-9]+(\\.[0-9]+)?$"

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "MyContainer",
"type": "object",
"properties": {

View file

@ -1,8 +1,8 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Tuple_of_Array_of_uint8_and_Array_of_uint8",
"type": "array",
"items": [
"prefixItems": [
{
"type": "array",
"items": {

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "ChronoTypes",
"type": "object",
"properties": {

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Struct",
"type": "object",
"properties": {

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "MyStruct",
"type": "object",
"properties": {
@ -13,21 +13,17 @@
"default": false
},
"my_struct2": {
"default": "i:0 b:false",
"allOf": [
{
"$ref": "#/definitions/MyStruct2"
}
]
"$ref": "#/$defs/MyStruct2",
"default": "i:0 b:false"
},
"my_struct2_default_skipped": {
"$ref": "#/definitions/MyStruct2"
"$ref": "#/$defs/MyStruct2"
},
"not_serialize": {
"$ref": "#/definitions/NotSerialize"
"$ref": "#/$defs/NotSerialize"
}
},
"definitions": {
"$defs": {
"MyStruct2": {
"type": "object",
"properties": {

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "DeprecatedEnum",
"oneOf": [
{

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "DeprecatedStruct",
"type": "object",
"properties": {

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "This is the enum's title",
"description": "This is the enum's description.",
"oneOf": [

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "OverrideDocs struct",
"description": "New description",
"type": "object",

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "This is the struct's title",
"description": "This is the struct's description.",
"type": "object",
@ -14,11 +14,7 @@
},
"my_unit": {
"description": "A unit struct instance",
"allOf": [
{
"$ref": "#/definitions/MyUnitStruct"
}
]
"$ref": "#/$defs/MyUnitStruct"
}
},
"required": [
@ -26,7 +22,7 @@
"my_undocumented_bool",
"my_unit"
],
"definitions": {
"$defs": {
"MyUnitStruct": {
"title": "A Unit",
"type": "null"

View file

@ -1,20 +1,20 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "MyStruct",
"type": "object",
"properties": {
"duration": {
"$ref": "#/definitions/Duration"
"$ref": "#/$defs/Duration"
},
"time": {
"$ref": "#/definitions/SystemTime"
"$ref": "#/$defs/SystemTime"
}
},
"required": [
"duration",
"time"
],
"definitions": {
"$defs": {
"Duration": {
"type": "object",
"properties": {

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Either_int32_or_Either_boolean_or_null",
"anyOf": [
{

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Adjacent",
"oneOf": [
{
@ -49,7 +49,7 @@
]
},
"c": {
"$ref": "#/definitions/UnitStruct"
"$ref": "#/$defs/UnitStruct"
}
},
"required": [
@ -68,7 +68,7 @@
]
},
"c": {
"$ref": "#/definitions/Struct"
"$ref": "#/$defs/Struct"
}
},
"required": [
@ -121,7 +121,7 @@
},
"c": {
"type": "array",
"items": [
"prefixItems": [
{
"type": "integer",
"format": "int32"
@ -176,7 +176,7 @@
"additionalProperties": false
}
],
"definitions": {
"$defs": {
"UnitStruct": {
"type": "null"
},

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Adjacent",
"oneOf": [
{
@ -47,7 +47,7 @@
]
},
"c": {
"$ref": "#/definitions/UnitStruct"
"$ref": "#/$defs/UnitStruct"
}
},
"required": [
@ -65,7 +65,7 @@
]
},
"c": {
"$ref": "#/definitions/Struct"
"$ref": "#/$defs/Struct"
}
},
"required": [
@ -115,7 +115,7 @@
},
"c": {
"type": "array",
"items": [
"prefixItems": [
{
"type": "integer",
"format": "int32"
@ -167,7 +167,7 @@
]
}
],
"definitions": {
"$defs": {
"UnitStruct": {
"type": "null"
},

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "External",
"oneOf": [
{
@ -28,7 +28,7 @@
"type": "object",
"properties": {
"unitStructNewType": {
"$ref": "#/definitions/UnitStruct"
"$ref": "#/$defs/UnitStruct"
}
},
"required": [
@ -40,7 +40,7 @@
"type": "object",
"properties": {
"structNewType": {
"$ref": "#/definitions/Struct"
"$ref": "#/$defs/Struct"
}
},
"required": [
@ -79,7 +79,7 @@
"properties": {
"tuple": {
"type": "array",
"items": [
"prefixItems": [
{
"type": "integer",
"format": "int32"
@ -111,7 +111,7 @@
"additionalProperties": false
}
],
"definitions": {
"$defs": {
"UnitStruct": {
"type": "null"
},

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "External",
"oneOf": [
{
@ -28,7 +28,7 @@
"type": "object",
"properties": {
"unitStructNewType": {
"$ref": "#/definitions/UnitStruct"
"$ref": "#/$defs/UnitStruct"
}
},
"required": [
@ -40,7 +40,7 @@
"type": "object",
"properties": {
"structNewType": {
"$ref": "#/definitions/Struct"
"$ref": "#/$defs/Struct"
}
},
"required": [
@ -78,7 +78,7 @@
"properties": {
"tuple": {
"type": "array",
"items": [
"prefixItems": [
{
"type": "integer",
"format": "int32"
@ -110,7 +110,7 @@
"additionalProperties": false
}
],
"definitions": {
"$defs": {
"UnitStruct": {
"type": "null"
},

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Internal",
"oneOf": [
{

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Internal",
"oneOf": [
{

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Renamed",
"description": "Description from comment",
"type": "integer",

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Enum",
"type": "integer",
"enum": [

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "SimpleInternal",
"oneOf": [
{

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "SimpleInternal",
"oneOf": [
{

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "SoundOfMusic",
"oneOf": [
{

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Untagged",
"anyOf": [
{
@ -12,10 +12,10 @@
}
},
{
"$ref": "#/definitions/UnitStruct"
"$ref": "#/$defs/UnitStruct"
},
{
"$ref": "#/definitions/Struct"
"$ref": "#/$defs/Struct"
},
{
"type": "object",
@ -36,7 +36,7 @@
},
{
"type": "array",
"items": [
"prefixItems": [
{
"type": "integer",
"format": "int32"
@ -53,7 +53,7 @@
"format": "int32"
}
],
"definitions": {
"$defs": {
"UnitStruct": {
"type": "null"
},

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Untagged",
"anyOf": [
{
@ -12,10 +12,10 @@
}
},
{
"$ref": "#/definitions/UnitStruct"
"$ref": "#/$defs/UnitStruct"
},
{
"$ref": "#/definitions/Struct"
"$ref": "#/$defs/Struct"
},
{
"type": "object",
@ -35,7 +35,7 @@
},
{
"type": "array",
"items": [
"prefixItems": [
{
"type": "integer",
"format": "int32"
@ -52,7 +52,7 @@
"format": "int32"
}
],
"definitions": {
"$defs": {
"UnitStruct": {
"type": "null"
},

View file

@ -1,12 +1,12 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Set_of_Foo",
"type": "array",
"uniqueItems": true,
"items": {
"$ref": "#/definitions/Foo"
"$ref": "#/$defs/Foo"
},
"definitions": {
"$defs": {
"Foo": {
"type": "string",
"enum": [

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Struct",
"type": "object",
"properties": {

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Flat",
"type": "object",
"properties": {

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"zero": {

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "IndexMapTypes",
"type": "object",
"properties": {

View file

@ -1,12 +1,12 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "RecursiveOuter",
"type": "object",
"properties": {
"direct": {
"anyOf": [
{
"$ref": "#/definitions/RecursiveOuter"
"$ref": "#/$defs/RecursiveOuter"
},
{
"type": "null"
@ -20,7 +20,7 @@
],
"properties": {
"recursive": {
"$ref": "#/definitions/RecursiveOuter"
"$ref": "#/$defs/RecursiveOuter"
}
},
"required": [
@ -28,14 +28,14 @@
]
}
},
"definitions": {
"$defs": {
"RecursiveOuter": {
"type": "object",
"properties": {
"direct": {
"anyOf": [
{
"$ref": "#/definitions/RecursiveOuter"
"$ref": "#/$defs/RecursiveOuter"
},
{
"type": "null"
@ -49,7 +49,7 @@
],
"properties": {
"recursive": {
"$ref": "#/definitions/RecursiveOuter"
"$ref": "#/$defs/RecursiveOuter"
}
},
"required": [

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "MyJob",
"type": "object",
"properties": {

View file

@ -1,12 +1,12 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "OuterEnum",
"oneOf": [
{
"type": "object",
"properties": {
"InnerStruct": {
"$ref": "#/definitions/InnerStruct"
"$ref": "#/$defs/InnerStruct"
}
},
"required": [
@ -15,7 +15,7 @@
"additionalProperties": false
}
],
"definitions": {
"$defs": {
"InnerStruct": {
"type": "object",
"properties": {

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "A",
"type": "object",
"properties": {

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "NoVariants",
"type": "string",
"enum": []

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "MyStruct",
"type": "object",
"properties": {

View file

@ -1,20 +1,20 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "OsStrings",
"type": "object",
"properties": {
"owned": {
"$ref": "#/definitions/OsString"
"$ref": "#/$defs/OsString"
},
"borrowed": {
"$ref": "#/definitions/OsString"
"$ref": "#/$defs/OsString"
}
},
"required": [
"owned",
"borrowed"
],
"definitions": {
"$defs": {
"OsString": {
"oneOf": [
{

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "MyStruct",
"type": "object",
"properties": {

View file

@ -1,16 +1,16 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "MyStruct",
"type": "object",
"properties": {
"range": {
"$ref": "#/definitions/Range_of_uint"
"$ref": "#/$defs/Range_of_uint"
},
"inclusive": {
"$ref": "#/definitions/Range_of_double"
"$ref": "#/$defs/Range_of_double"
},
"bound": {
"$ref": "#/definitions/Bound_of_string"
"$ref": "#/$defs/Bound_of_string"
}
},
"required": [
@ -18,7 +18,7 @@
"inclusive",
"bound"
],
"definitions": {
"$defs": {
"Range_of_uint": {
"type": "object",
"properties": {

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Process",
"type": "object",
"properties": {
@ -7,33 +7,25 @@
"type": "string"
},
"wall_time": {
"$ref": "#/definitions/Duration"
"$ref": "#/$defs/Duration"
},
"user_cpu_time": {
"$ref": "#/$defs/Duration",
"default": {
"secs": 0,
"nanos": 0
},
"allOf": [
{
"$ref": "#/definitions/Duration"
}
]
}
},
"system_cpu_time": {
"default": "0.000000000s",
"allOf": [
{
"$ref": "#/definitions/Duration"
}
]
"$ref": "#/$defs/Duration",
"default": "0.000000000s"
}
},
"required": [
"command_line",
"wall_time"
],
"definitions": {
"$defs": {
"Duration": {
"type": "object",
"properties": {

View file

@ -1,16 +1,16 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "MyStruct_for_int32",
"type": "object",
"properties": {
"byte_or_bool2": {
"$ref": "#/definitions/Or_for_uint8_and_boolean"
"$ref": "#/$defs/Or_for_uint8_and_boolean"
},
"unit_or_t2": {
"$ref": "#/definitions/Or_for_null_and_int32"
"$ref": "#/$defs/Or_for_null_and_int32"
},
"s": {
"$ref": "#/definitions/Str"
"$ref": "#/$defs/Str"
},
"fake_map": {
"type": "object",
@ -29,7 +29,7 @@
"s",
"fake_map"
],
"definitions": {
"$defs": {
"Or_for_uint8_and_boolean": {
"anyOf": [
{

View file

@ -1,27 +1,27 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Container",
"type": "object",
"properties": {
"result1": {
"$ref": "#/definitions/Result_of_MyStruct_or_Array_of_string"
"$ref": "#/$defs/Result_of_MyStruct_or_Array_of_string"
},
"result2": {
"$ref": "#/definitions/Result_of_boolean_or_null"
"$ref": "#/$defs/Result_of_boolean_or_null"
}
},
"required": [
"result1",
"result2"
],
"definitions": {
"$defs": {
"Result_of_MyStruct_or_Array_of_string": {
"oneOf": [
{
"type": "object",
"properties": {
"Ok": {
"$ref": "#/definitions/MyStruct"
"$ref": "#/$defs/MyStruct"
}
},
"required": [

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Decimal",
"type": "string",
"pattern": "^-?[0-9]+(\\.[0-9]+)?$"

View file

@ -1,20 +1,20 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Config2",
"type": "object",
"properties": {
"a_cfg": {
"$ref": "#/definitions/Config"
"$ref": "#/$defs/Config"
},
"b_cfg": {
"$ref": "#/definitions/Config2"
"$ref": "#/$defs/Config2"
}
},
"required": [
"a_cfg",
"b_cfg"
],
"definitions": {
"$defs": {
"Config": {
"type": "object",
"properties": {

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "const-generics-z-42",
"type": "object",
"properties": {

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "a-new-name-Array_of_string-int32-int32",
"type": "object",
"properties": {
@ -20,7 +20,7 @@
}
},
"inner": {
"$ref": "#/definitions/another-new-name"
"$ref": "#/$defs/another-new-name"
}
},
"required": [
@ -30,7 +30,7 @@
"w",
"inner"
],
"definitions": {
"$defs": {
"another-new-name": {
"type": "object",
"properties": {

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "MyStruct_for_int32_and_null_and_boolean_and_Array_of_string",
"type": "object",
"properties": {
@ -20,7 +20,7 @@
}
},
"inner": {
"$ref": "#/definitions/MySimpleStruct"
"$ref": "#/$defs/MySimpleStruct"
}
},
"required": [
@ -30,7 +30,7 @@
"w",
"inner"
],
"definitions": {
"$defs": {
"MySimpleStruct": {
"type": "object",
"properties": {

View file

@ -1,10 +1,10 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "MixedGenericStruct_for_MyStruct_for_int32_and_null_and_boolean_and_Array_of_string_and_42_and_z",
"type": "object",
"properties": {
"generic": {
"$ref": "#/definitions/MyStruct_for_int32_and_null_and_boolean_and_Array_of_string"
"$ref": "#/$defs/MyStruct_for_int32_and_null_and_boolean_and_Array_of_string"
},
"foo": {
"type": "integer",
@ -15,7 +15,7 @@
"generic",
"foo"
],
"definitions": {
"$defs": {
"MyStruct_for_int32_and_null_and_boolean_and_Array_of_string": {
"type": "object",
"properties": {
@ -36,7 +36,7 @@
}
},
"inner": {
"$ref": "#/definitions/MySimpleStruct"
"$ref": "#/$defs/MySimpleStruct"
}
},
"required": [

View file

@ -25,12 +25,32 @@
"type": "null"
}
]
},
"tuples": {
"type": "array",
"items": {
"type": "array",
"items": [
{
"type": "integer",
"format": "uint8",
"minimum": 0
},
{
"type": "integer",
"format": "int64"
}
],
"minItems": 2,
"maxItems": 2
}
}
},
"required": [
"int",
"values",
"value"
"value",
"tuples"
],
"$defs": {
"Inner": {

View file

@ -0,0 +1,83 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Outer",
"type": "object",
"properties": {
"int": {
"type": "integer",
"format": "int32",
"examples": [
8,
null
]
},
"values": {
"type": "object",
"additionalProperties": true
},
"value": true,
"inner": {
"anyOf": [
{
"$ref": "#/$defs/Inner"
},
{
"type": "null"
}
]
},
"tuples": {
"type": "array",
"items": {
"type": "array",
"prefixItems": [
{
"type": "integer",
"format": "uint8",
"minimum": 0
},
{
"type": "integer",
"format": "int64"
}
],
"minItems": 2,
"maxItems": 2
}
}
},
"required": [
"int",
"values",
"value",
"tuples"
],
"$defs": {
"Inner": {
"oneOf": [
{
"type": "string",
"enum": [
"UndocumentedUnit1",
"UndocumentedUnit2"
]
},
{
"description": "This is a documented unit variant",
"type": "string",
"const": "DocumentedUnit"
},
{
"type": "object",
"properties": {
"ValueNewType": true
},
"required": [
"ValueNewType"
],
"additionalProperties": false
}
]
}
}
}

View file

@ -20,12 +20,32 @@
"$ref": "#/components/schemas/Inner"
}
]
},
"tuples": {
"type": "array",
"items": {
"type": "array",
"items": [
{
"type": "integer",
"format": "uint8",
"minimum": 0
},
{
"type": "integer",
"format": "int64"
}
],
"minItems": 2,
"maxItems": 2
}
}
},
"required": [
"int",
"values",
"value"
"value",
"tuples"
],
"components": {
"schemas": {

View file

@ -25,12 +25,32 @@
"type": "null"
}
]
},
"tuples": {
"type": "array",
"items": {
"type": "array",
"items": [
{
"type": "integer",
"format": "uint8",
"minimum": 0
},
{
"type": "integer",
"format": "int64"
}
],
"minItems": 2,
"maxItems": 2
}
}
},
"required": [
"int",
"values",
"value"
"value",
"tuples"
],
"definitions": {
"Inner": {

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Adjacent",
"oneOf": [
{
@ -57,7 +57,7 @@
},
"c": {
"type": "array",
"items": [
"prefixItems": [
{
"type": "boolean"
},

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "External",
"oneOf": [
{
@ -39,7 +39,7 @@
"properties": {
"tuple": {
"type": "array",
"items": [
"prefixItems": [
{
"type": "boolean"
},

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Internal",
"oneOf": [
{

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Untagged",
"anyOf": [
{
@ -18,7 +18,7 @@
},
{
"type": "array",
"items": [
"prefixItems": [
{
"type": "boolean"
},

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Newtype",
"type": "boolean"
}

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Struct",
"type": "object",
"properties": {

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "schema_fn",
"type": "boolean"
}

View file

@ -1,8 +1,8 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Tuple",
"type": "array",
"items": [
"prefixItems": [
{
"type": "boolean"
},

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "SemverTypes",
"type": "object",
"properties": {

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "MyEnum",
"oneOf": [
{

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "MyStruct",
"type": "object",
"properties": {

View file

@ -1,8 +1,8 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "TupleStruct",
"type": "array",
"items": [
"prefixItems": [
{
"type": "number",
"format": "float"

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Array_of_string",
"type": "array",
"items": {

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "string",
"type": "string"
}

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Newtype",
"type": "integer",
"format": "int32"

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Struct",
"type": "object",
"properties": {

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Struct",
"type": "object",
"properties": {

View file

@ -1,8 +1,8 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Tuple",
"type": "array",
"items": [
"prefixItems": [
{
"type": "integer",
"format": "int32"

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Unit",
"type": "null"
}

View file

@ -1,12 +1,12 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "OuterStruct",
"type": "object",
"properties": {
"inner": {
"anyOf": [
{
"$ref": "#/definitions/InnerStruct"
"$ref": "#/$defs/InnerStruct"
},
{
"type": "null"
@ -14,10 +14,10 @@
]
}
},
"definitions": {
"$defs": {
"InnerStruct": {
"type": "array",
"items": [
"prefixItems": [
{
"type": "string"
},

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "UrlTypes",
"type": "object",
"properties": {

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Uuid",
"type": "string",
"format": "uuid"

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Struct",
"type": "object",
"properties": {

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Struct",
"type": "object",
"properties": {

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "NewType",
"type": "integer",
"format": "uint8",

View file

@ -1,5 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Struct2",
"type": "object",
"properties": {

View file

@ -1,8 +1,8 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Tuple",
"type": "array",
"items": [
"prefixItems": [
{
"type": "integer",
"format": "uint8",

View file

@ -12,6 +12,7 @@ pub struct Outer {
pub values: BTreeMap<&'static str, Value>,
pub value: Value,
pub inner: Option<Inner>,
pub tuples: Vec<(u8, i64)>,
}
#[derive(JsonSchema)]
@ -39,6 +40,11 @@ fn schema_matches_2019_09() -> TestResult {
test_generated_schema::<Outer>("schema_settings-2019_09", SchemaSettings::draft2019_09())
}
#[test]
fn schema_matches_2020_12() -> TestResult {
test_generated_schema::<Outer>("schema_settings-2020_12", SchemaSettings::draft2020_12())
}
#[test]
fn schema_matches_openapi3() -> TestResult {
test_generated_schema::<Outer>("schema_settings-openapi3", SchemaSettings::openapi3())

View file

@ -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,
})