Simplify schema for Options
This commit is contained in:
parent
d7a214526f
commit
13267d37d7
3 changed files with 144 additions and 192 deletions
|
@ -20,6 +20,12 @@ impl<T: JsonSchema> JsonSchema for Option<T> {
|
||||||
schema = match schema {
|
schema = match schema {
|
||||||
Schema::Bool(true) => Schema::Bool(true),
|
Schema::Bool(true) => Schema::Bool(true),
|
||||||
Schema::Bool(false) => <()>::json_schema(gen)?,
|
Schema::Bool(false) => <()>::json_schema(gen)?,
|
||||||
|
Schema::Object(
|
||||||
|
obj @ SchemaObject {
|
||||||
|
instance_type: Some(_),
|
||||||
|
..
|
||||||
|
},
|
||||||
|
) => Schema::Object(with_null_type(obj)),
|
||||||
schema => SchemaObject {
|
schema => SchemaObject {
|
||||||
any_of: Some(vec![schema, <()>::json_schema(gen)?]),
|
any_of: Some(vec![schema, <()>::json_schema(gen)?]),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
@ -36,6 +42,20 @@ impl<T: JsonSchema> JsonSchema for Option<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn with_null_type(mut obj: SchemaObject) -> SchemaObject {
|
||||||
|
match obj
|
||||||
|
.instance_type
|
||||||
|
.as_mut()
|
||||||
|
.expect("checked in calling function")
|
||||||
|
{
|
||||||
|
SingleOrVec::Single(ty) if **ty == InstanceType::Null => {}
|
||||||
|
SingleOrVec::Vec(ty) if ty.contains(&InstanceType::Null) => {}
|
||||||
|
SingleOrVec::Single(ty) => obj.instance_type = Some(vec![**ty, InstanceType::Null].into()),
|
||||||
|
SingleOrVec::Vec(ref mut ty) => ty.push(InstanceType::Null),
|
||||||
|
};
|
||||||
|
obj
|
||||||
|
}
|
||||||
|
|
||||||
impl<T: ?Sized> JsonSchema for std::marker::PhantomData<T> {
|
impl<T: ?Sized> JsonSchema for std::marker::PhantomData<T> {
|
||||||
no_ref_schema!();
|
no_ref_schema!();
|
||||||
|
|
||||||
|
@ -70,12 +90,32 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn schema_for_option() {
|
fn schema_for_option() {
|
||||||
let schema = schema_object_for::<Option<i32>>();
|
let schema = schema_object_for::<Option<i32>>();
|
||||||
|
assert_eq!(
|
||||||
|
schema.instance_type,
|
||||||
|
Some(vec![InstanceType::Integer, InstanceType::Null].into())
|
||||||
|
);
|
||||||
|
assert_eq!(schema.extensions.get("nullable"), None);
|
||||||
|
assert_eq!(schema.any_of.is_none(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn schema_for_option_with_ref() {
|
||||||
|
use crate as schemars;
|
||||||
|
#[derive(JsonSchema)]
|
||||||
|
struct Foo;
|
||||||
|
|
||||||
|
let schema = schema_object_for::<Option<Foo>>();
|
||||||
assert_eq!(schema.instance_type, None);
|
assert_eq!(schema.instance_type, None);
|
||||||
assert_eq!(schema.extensions.get("nullable"), None);
|
assert_eq!(schema.extensions.get("nullable"), None);
|
||||||
assert_eq!(schema.any_of.is_some(), true);
|
assert_eq!(schema.any_of.is_some(), true);
|
||||||
let any_of = schema.any_of.unwrap();
|
let any_of = schema.any_of.unwrap();
|
||||||
assert_eq!(any_of.len(), 2);
|
assert_eq!(any_of.len(), 2);
|
||||||
assert_eq!(any_of[0], schema_for::<i32>());
|
assert_eq!(
|
||||||
|
any_of[0],
|
||||||
|
Schema::Ref(Ref {
|
||||||
|
reference: "#/definitions/Foo".to_string()
|
||||||
|
})
|
||||||
|
);
|
||||||
assert_eq!(any_of[1], schema_for::<()>());
|
assert_eq!(any_of[1], schema_for::<()>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -144,7 +144,7 @@ pub struct ObjectValidation {
|
||||||
pub property_names: Option<Box<Schema>>,
|
pub property_names: Option<Box<Schema>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, JsonSchema)]
|
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, JsonSchema)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub enum InstanceType {
|
pub enum InstanceType {
|
||||||
Null,
|
Null,
|
||||||
|
|
|
@ -52,23 +52,15 @@
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"$id": {
|
"$id": {
|
||||||
"anyOf": [
|
"type": [
|
||||||
{
|
"string",
|
||||||
"type": "string"
|
"null"
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "null"
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"$schema": {
|
"$schema": {
|
||||||
"anyOf": [
|
"type": [
|
||||||
{
|
"string",
|
||||||
"type": "string"
|
"null"
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "null"
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"additionalItems": {
|
"additionalItems": {
|
||||||
|
@ -92,30 +84,22 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"allOf": {
|
"allOf": {
|
||||||
"anyOf": [
|
"type": [
|
||||||
{
|
"array",
|
||||||
"type": "array",
|
"null"
|
||||||
"items": {
|
],
|
||||||
"$ref": "#/definitions/Schema"
|
"items": {
|
||||||
}
|
"$ref": "#/definitions/Schema"
|
||||||
},
|
}
|
||||||
{
|
|
||||||
"type": "null"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"anyOf": {
|
"anyOf": {
|
||||||
"anyOf": [
|
"type": [
|
||||||
{
|
"array",
|
||||||
"type": "array",
|
"null"
|
||||||
"items": {
|
],
|
||||||
"$ref": "#/definitions/Schema"
|
"items": {
|
||||||
}
|
"$ref": "#/definitions/Schema"
|
||||||
},
|
}
|
||||||
{
|
|
||||||
"type": "null"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"const": true,
|
"const": true,
|
||||||
"contains": {
|
"contains": {
|
||||||
|
@ -135,13 +119,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"anyOf": [
|
"type": [
|
||||||
{
|
"string",
|
||||||
"type": "string"
|
"null"
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "null"
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"else": {
|
"else": {
|
||||||
|
@ -155,46 +135,30 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"enum": {
|
"enum": {
|
||||||
"anyOf": [
|
"type": [
|
||||||
{
|
"array",
|
||||||
"type": "array",
|
"null"
|
||||||
"items": true
|
],
|
||||||
},
|
"items": true
|
||||||
{
|
|
||||||
"type": "null"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"exclusiveMaximum": {
|
"exclusiveMaximum": {
|
||||||
"anyOf": [
|
"type": [
|
||||||
{
|
"number",
|
||||||
"type": "number",
|
"null"
|
||||||
"format": "double"
|
],
|
||||||
},
|
"format": "double"
|
||||||
{
|
|
||||||
"type": "null"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"exclusiveMinimum": {
|
"exclusiveMinimum": {
|
||||||
"anyOf": [
|
"type": [
|
||||||
{
|
"number",
|
||||||
"type": "number",
|
"null"
|
||||||
"format": "double"
|
],
|
||||||
},
|
"format": "double"
|
||||||
{
|
|
||||||
"type": "null"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"format": {
|
"format": {
|
||||||
"anyOf": [
|
"type": [
|
||||||
{
|
"string",
|
||||||
"type": "string"
|
"null"
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "null"
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"if": {
|
"if": {
|
||||||
|
@ -218,103 +182,67 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"maxItems": {
|
"maxItems": {
|
||||||
"anyOf": [
|
"type": [
|
||||||
{
|
"integer",
|
||||||
"type": "integer",
|
"null"
|
||||||
"format": "uint32"
|
],
|
||||||
},
|
"format": "uint32"
|
||||||
{
|
|
||||||
"type": "null"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"maxLength": {
|
"maxLength": {
|
||||||
"anyOf": [
|
"type": [
|
||||||
{
|
"integer",
|
||||||
"type": "integer",
|
"null"
|
||||||
"format": "uint32"
|
],
|
||||||
},
|
"format": "uint32"
|
||||||
{
|
|
||||||
"type": "null"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"maxProperties": {
|
"maxProperties": {
|
||||||
"anyOf": [
|
"type": [
|
||||||
{
|
"integer",
|
||||||
"type": "integer",
|
"null"
|
||||||
"format": "uint32"
|
],
|
||||||
},
|
"format": "uint32"
|
||||||
{
|
|
||||||
"type": "null"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"maximum": {
|
"maximum": {
|
||||||
"anyOf": [
|
"type": [
|
||||||
{
|
"number",
|
||||||
"type": "number",
|
"null"
|
||||||
"format": "double"
|
],
|
||||||
},
|
"format": "double"
|
||||||
{
|
|
||||||
"type": "null"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"minItems": {
|
"minItems": {
|
||||||
"anyOf": [
|
"type": [
|
||||||
{
|
"integer",
|
||||||
"type": "integer",
|
"null"
|
||||||
"format": "uint32"
|
],
|
||||||
},
|
"format": "uint32"
|
||||||
{
|
|
||||||
"type": "null"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"minLength": {
|
"minLength": {
|
||||||
"anyOf": [
|
"type": [
|
||||||
{
|
"integer",
|
||||||
"type": "integer",
|
"null"
|
||||||
"format": "uint32"
|
],
|
||||||
},
|
"format": "uint32"
|
||||||
{
|
|
||||||
"type": "null"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"minProperties": {
|
"minProperties": {
|
||||||
"anyOf": [
|
"type": [
|
||||||
{
|
"integer",
|
||||||
"type": "integer",
|
"null"
|
||||||
"format": "uint32"
|
],
|
||||||
},
|
"format": "uint32"
|
||||||
{
|
|
||||||
"type": "null"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"minimum": {
|
"minimum": {
|
||||||
"anyOf": [
|
"type": [
|
||||||
{
|
"number",
|
||||||
"type": "number",
|
"null"
|
||||||
"format": "double"
|
],
|
||||||
},
|
"format": "double"
|
||||||
{
|
|
||||||
"type": "null"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"multipleOf": {
|
"multipleOf": {
|
||||||
"anyOf": [
|
"type": [
|
||||||
{
|
"number",
|
||||||
"type": "number",
|
"null"
|
||||||
"format": "double"
|
],
|
||||||
},
|
"format": "double"
|
||||||
{
|
|
||||||
"type": "null"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"not": {
|
"not": {
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
|
@ -327,26 +255,18 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"oneOf": {
|
"oneOf": {
|
||||||
"anyOf": [
|
"type": [
|
||||||
{
|
"array",
|
||||||
"type": "array",
|
"null"
|
||||||
"items": {
|
],
|
||||||
"$ref": "#/definitions/Schema"
|
"items": {
|
||||||
}
|
"$ref": "#/definitions/Schema"
|
||||||
},
|
}
|
||||||
{
|
|
||||||
"type": "null"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"pattern": {
|
"pattern": {
|
||||||
"anyOf": [
|
"type": [
|
||||||
{
|
"string",
|
||||||
"type": "string"
|
"null"
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "null"
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"patternProperties": {
|
"patternProperties": {
|
||||||
|
@ -388,13 +308,9 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"title": {
|
"title": {
|
||||||
"anyOf": [
|
"type": [
|
||||||
{
|
"string",
|
||||||
"type": "string"
|
"null"
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "null"
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"type": {
|
"type": {
|
||||||
|
@ -408,13 +324,9 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"uniqueItems": {
|
"uniqueItems": {
|
||||||
"anyOf": [
|
"type": [
|
||||||
{
|
"boolean",
|
||||||
"type": "boolean"
|
"null"
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "null"
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue