From 5503f0697f190280aa7c468a9a3b4cef7e52ebe2 Mon Sep 17 00:00:00 2001 From: Graham Esau Date: Wed, 30 Oct 2019 19:39:44 +0000 Subject: [PATCH] Implement JsonSchema for Bound --- schemars/src/json_schema_impls/core.rs | 34 +++++++++++++++++++++++++- schemars/tests/expected/range.json | 34 ++++++++++++++++++++++++++ schemars/tests/range.rs | 3 ++- 3 files changed, 69 insertions(+), 2 deletions(-) diff --git a/schemars/src/json_schema_impls/core.rs b/schemars/src/json_schema_impls/core.rs index 28d08b6..b4fe2b9 100644 --- a/schemars/src/json_schema_impls/core.rs +++ b/schemars/src/json_schema_impls/core.rs @@ -2,7 +2,7 @@ use crate::gen::SchemaGenerator; use crate::schema::*; use crate::JsonSchema; use serde_json::json; -use std::ops::{Range, RangeInclusive}; +use std::ops::{Bound, Range, RangeInclusive}; impl JsonSchema for Option { no_ref_schema!(); @@ -100,6 +100,38 @@ impl JsonSchema for Result { } } +impl JsonSchema for Bound { + fn schema_name() -> String { + format!("Bound_of_{}", T::schema_name()) + } + + fn json_schema(gen: &mut SchemaGenerator) -> Schema { + let mut included_schema = SchemaObject::default(); + included_schema.instance_type = Some(InstanceType::Object.into()); + included_schema.object().required.insert("Included".to_owned()); + included_schema + .object() + .properties + .insert("Included".to_owned(), gen.subschema_for::()); + + let mut excluded_schema = SchemaObject::default(); + excluded_schema.instance_type = Some(InstanceType::Object.into()); + excluded_schema.object().required.insert("Excluded".to_owned()); + excluded_schema + .object() + .properties + .insert("Excluded".to_owned(), gen.subschema_for::()); + + let mut unbounded_schema = SchemaObject::default(); + unbounded_schema.instance_type = Some(InstanceType::String.into()); + unbounded_schema.const_value = Some(json!("Unbounded")); + + let mut schema = SchemaObject::default(); + schema.subschemas().one_of = Some(vec![included_schema.into(), excluded_schema.into(), unbounded_schema.into()]); + schema.into() + } +} + impl JsonSchema for Range { fn schema_name() -> String { format!("Range_of_{}", T::schema_name()) diff --git a/schemars/tests/expected/range.json b/schemars/tests/expected/range.json index f5d53cb..65fee56 100644 --- a/schemars/tests/expected/range.json +++ b/schemars/tests/expected/range.json @@ -3,10 +3,14 @@ "title": "MyStruct", "type": "object", "required": [ + "bound", "inclusive", "range" ], "properties": { + "bound": { + "$ref": "#/definitions/Bound_of_String" + }, "inclusive": { "$ref": "#/definitions/Range_of_double" }, @@ -15,6 +19,36 @@ } }, "definitions": { + "Bound_of_String": { + "oneOf": [ + { + "type": "object", + "required": [ + "Included" + ], + "properties": { + "Included": { + "type": "string" + } + } + }, + { + "type": "object", + "required": [ + "Excluded" + ], + "properties": { + "Excluded": { + "type": "string" + } + } + }, + { + "type": "string", + "const": "Unbounded" + } + ] + }, "Range_of_double": { "type": "object", "required": [ diff --git a/schemars/tests/range.rs b/schemars/tests/range.rs index 19b5ad2..d120a8f 100644 --- a/schemars/tests/range.rs +++ b/schemars/tests/range.rs @@ -1,12 +1,13 @@ mod util; use schemars::JsonSchema; +use std::ops::{Bound, Range, RangeInclusive}; use util::*; -use std::ops::{Range, RangeInclusive}; #[derive(Debug, JsonSchema)] struct MyStruct { range: Range, inclusive: RangeInclusive, + bound: Bound } #[test]