Update doc comments and make SchemaGenerator available from crate root

This commit is contained in:
Graham Esau 2024-05-27 11:09:15 +01:00
parent fb6e1a5c61
commit 760403e2f5
13 changed files with 150 additions and 74 deletions

View file

@ -36,10 +36,9 @@ println!("{}", serde_json::to_string_pretty(&schema).unwrap());
```json ```json
{ {
"$schema": "http://json-schema.org/draft-07/schema#", "$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "MyStruct", "title": "MyStruct",
"type": "object", "type": "object",
"required": ["my_bool", "my_int"],
"properties": { "properties": {
"my_bool": { "my_bool": {
"type": "boolean" "type": "boolean"
@ -51,7 +50,7 @@ println!("{}", serde_json::to_string_pretty(&schema).unwrap());
"my_nullable_enum": { "my_nullable_enum": {
"anyOf": [ "anyOf": [
{ {
"$ref": "#/definitions/MyEnum" "$ref": "#/$defs/MyEnum"
}, },
{ {
"type": "null" "type": "null"
@ -59,26 +58,25 @@ println!("{}", serde_json::to_string_pretty(&schema).unwrap());
] ]
} }
}, },
"definitions": { "required": ["my_int", "my_bool"],
"$defs": {
"MyEnum": { "MyEnum": {
"anyOf": [ "oneOf": [
{ {
"type": "object", "type": "object",
"required": ["StringNewType"],
"properties": { "properties": {
"StringNewType": { "StringNewType": {
"type": "string" "type": "string"
} }
}, },
"additionalProperties": false "additionalProperties": false,
"required": ["StringNewType"]
}, },
{ {
"type": "object", "type": "object",
"required": ["StructVariant"],
"properties": { "properties": {
"StructVariant": { "StructVariant": {
"type": "object", "type": "object",
"required": ["floats"],
"properties": { "properties": {
"floats": { "floats": {
"type": "array", "type": "array",
@ -87,10 +85,12 @@ println!("{}", serde_json::to_string_pretty(&schema).unwrap());
"format": "float" "format": "float"
} }
} }
} },
"required": ["floats"]
} }
}, },
"additionalProperties": false "additionalProperties": false,
"required": ["StructVariant"]
} }
] ]
} }
@ -134,24 +134,23 @@ println!("{}", serde_json::to_string_pretty(&schema).unwrap());
```json ```json
{ {
"$schema": "http://json-schema.org/draft-07/schema#", "$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "MyStruct", "title": "MyStruct",
"type": "object", "type": "object",
"required": ["myBool", "myNumber"],
"properties": { "properties": {
"myBool": { "myBool": {
"type": "boolean" "type": "boolean"
}, },
"myNullableEnum": { "myNullableEnum": {
"default": null,
"anyOf": [ "anyOf": [
{ {
"$ref": "#/definitions/MyEnum" "$ref": "#/$defs/MyEnum"
}, },
{ {
"type": "null" "type": "null"
} }
] ],
"default": null
}, },
"myNumber": { "myNumber": {
"type": "integer", "type": "integer",
@ -159,7 +158,8 @@ println!("{}", serde_json::to_string_pretty(&schema).unwrap());
} }
}, },
"additionalProperties": false, "additionalProperties": false,
"definitions": { "required": ["myNumber", "myBool"],
"$defs": {
"MyEnum": { "MyEnum": {
"anyOf": [ "anyOf": [
{ {
@ -167,7 +167,6 @@ println!("{}", serde_json::to_string_pretty(&schema).unwrap());
}, },
{ {
"type": "object", "type": "object",
"required": ["floats"],
"properties": { "properties": {
"floats": { "floats": {
"type": "array", "type": "array",
@ -176,7 +175,8 @@ println!("{}", serde_json::to_string_pretty(&schema).unwrap());
"format": "float" "format": "float"
} }
} }
} },
"required": ["floats"]
} }
] ]
} }

View file

@ -1,5 +1,4 @@
use schemars::Schema; use schemars::{schema_for, JsonSchema, Schema, SchemaGenerator};
use schemars::{gen::SchemaGenerator, schema_for, JsonSchema};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
// `int_as_string` and `bool_as_string` use the schema for `String`. // `int_as_string` and `bool_as_string` use the schema for `String`.

View file

@ -1,5 +1,4 @@
use schemars::Schema; use schemars::{schema_for, JsonSchema, Schema, SchemaGenerator};
use schemars::{gen::SchemaGenerator, schema_for, JsonSchema};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
// `int_as_string` and `bool_as_string` use the schema for `String`. // `int_as_string` and `bool_as_string` use the schema for `String`.

View file

@ -1,11 +1,6 @@
use crate::gen::SchemaGenerator; use crate::{JsonSchema, Schema, SchemaGenerator};
use crate::JsonSchema;
use crate::Schema;
use serde::Serialize; use serde::Serialize;
use serde_json::json; use serde_json::{json, map::Entry, Map, Value};
use serde_json::map::Entry;
use serde_json::Map;
use serde_json::Value;
// Helper for generating schemas for flattened `Option` fields. // Helper for generating schemas for flattened `Option` fields.
pub fn json_schema_for_flatten<T: ?Sized + JsonSchema>( pub fn json_schema_for_flatten<T: ?Sized + JsonSchema>(

View file

@ -12,8 +12,8 @@ use crate::{visit::*, JsonSchema};
use dyn_clone::DynClone; use dyn_clone::DynClone;
use serde::Serialize; use serde::Serialize;
use serde_json::{Map, Value}; use serde_json::{Map, Value};
use std::collections::HashMap; use std::collections::{HashMap, HashSet};
use std::{any::Any, collections::HashSet, fmt::Debug}; use std::{any::Any, fmt::Debug};
type CowStr = std::borrow::Cow<'static, str>; type CowStr = std::borrow::Cow<'static, str>;
@ -38,7 +38,7 @@ pub struct SchemaSettings {
/// ///
/// A single leading `#` and/or single trailing `/` are ignored. /// A single leading `#` and/or single trailing `/` are ignored.
/// ///
/// Defaults to `/$defs`. /// Defaults to `"/$defs"`.
pub definitions_path: String, pub definitions_path: String,
/// The URI of the meta-schema describing the structure of the generated schemas. /// The URI of the meta-schema describing the structure of the generated schemas.
/// ///
@ -55,6 +55,8 @@ pub struct SchemaSettings {
} }
impl Default for SchemaSettings { impl Default for SchemaSettings {
/// 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.
fn default() -> SchemaSettings { fn default() -> SchemaSettings {
SchemaSettings::draft2020_12() SchemaSettings::draft2020_12()
} }
@ -97,7 +99,7 @@ impl SchemaSettings {
} }
} }
/// Creates `SchemaSettings` that conform to [OpenAPI 3.0](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#schemaObject). /// Creates `SchemaSettings` that conform to [OpenAPI 3.0](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#schema).
pub fn openapi3() -> SchemaSettings { pub fn openapi3() -> SchemaSettings {
SchemaSettings { SchemaSettings {
option_nullable: true, option_nullable: true,
@ -153,7 +155,7 @@ impl SchemaSettings {
/// ///
/// # Example /// # Example
/// ``` /// ```
/// use schemars::{JsonSchema, gen::SchemaGenerator}; /// use schemars::{JsonSchema, SchemaGenerator};
/// ///
/// #[derive(JsonSchema)] /// #[derive(JsonSchema)]
/// struct MyStruct { /// struct MyStruct {
@ -203,7 +205,7 @@ impl SchemaGenerator {
/// ///
/// # Example /// # Example
/// ``` /// ```
/// use schemars::gen::SchemaGenerator; /// use schemars::SchemaGenerator;
/// ///
/// let gen = SchemaGenerator::default(); /// let gen = SchemaGenerator::default();
/// let settings = gen.settings(); /// let settings = gen.settings();
@ -287,7 +289,7 @@ impl SchemaGenerator {
} }
/// Returns the collection of all [non-inlined](JsonSchema::always_inline_schema) schemas that have been generated, /// Returns the collection of all [non-inlined](JsonSchema::always_inline_schema) schemas that have been generated,
/// leaving an empty map in its place. /// leaving an empty `Map` in its place.
/// ///
/// The keys of the returned `Map` are the [schema names](JsonSchema::schema_name), and the values are the schemas /// The keys of the returned `Map` are the [schema names](JsonSchema::schema_name), and the values are the schemas
/// themselves. /// themselves.
@ -300,11 +302,10 @@ impl SchemaGenerator {
self.settings.visitors.iter_mut().map(|v| v.as_mut()) self.settings.visitors.iter_mut().map(|v| v.as_mut())
} }
/// Generates a root JSON Schema for the type `T`. /// Generates a JSON Schema for the type `T`.
/// ///
/// If `T`'s schema depends on any [non-inlined](JsonSchema::always_inline_schema) schemas, then this method will /// If `T`'s schema depends on any [non-inlined](JsonSchema::always_inline_schema) schemas, then this method will
/// add them to the `SchemaGenerator`'s schema definitions and include them in the returned `SchemaObject`'s /// include them in the returned `Schema` at the [definitions path](SchemaSettings::definitions_path) (by default `"$defs"`).
/// [`definitions`](../schema/struct.Metadata.html#structfield.definitions)
pub fn root_schema_for<T: ?Sized + JsonSchema>(&mut self) -> Schema { pub fn root_schema_for<T: ?Sized + JsonSchema>(&mut self) -> Schema {
let mut schema = self.json_schema_internal::<T>(T::schema_id()); let mut schema = self.json_schema_internal::<T>(T::schema_id());
@ -324,10 +325,10 @@ impl SchemaGenerator {
schema schema
} }
/// Consumes `self` and generates a root JSON Schema for the type `T`. /// Consumes `self` and generates a JSON Schema for the type `T`.
/// ///
/// If `T`'s schema depends on any [non-inlined](JsonSchema::always_inline_schema) schemas, then this method will /// If `T`'s schema depends on any [non-inlined](JsonSchema::always_inline_schema) schemas, then this method will
/// include them in the returned `SchemaObject`'s [`definitions`](../schema/struct.Metadata.html#structfield.definitions) /// include them in the returned `Schema` at the [definitions path](SchemaSettings::definitions_path) (by default `"$defs"`).
pub fn into_root_schema_for<T: ?Sized + JsonSchema>(mut self) -> Schema { pub fn into_root_schema_for<T: ?Sized + JsonSchema>(mut self) -> Schema {
let mut schema = self.json_schema_internal::<T>(T::schema_id()); let mut schema = self.json_schema_internal::<T>(T::schema_id());
@ -348,10 +349,12 @@ impl SchemaGenerator {
schema schema
} }
/// Generates a root JSON Schema for the given example value. /// Generates a JSON Schema for the given example value.
/// ///
/// If the value implements [`JsonSchema`](crate::JsonSchema), then prefer using the [`root_schema_for()`](Self::root_schema_for()) /// If the value implements [`JsonSchema`](crate::JsonSchema), then prefer using the [`root_schema_for()`](Self::root_schema_for())
/// function which will generally produce a more precise schema, particularly when the value contains any enums. /// function which will generally produce a more precise schema, particularly when the value contains any enums.
///
/// If the `Serialize` implementation of the value decides to fail, this will return an [`Err`].
pub fn root_schema_for_value<T: ?Sized + Serialize>( pub fn root_schema_for_value<T: ?Sized + Serialize>(
&mut self, &mut self,
value: &T, value: &T,
@ -377,10 +380,12 @@ impl SchemaGenerator {
Ok(schema) Ok(schema)
} }
/// Consumes `self` and generates a root JSON Schema for the given example value. /// Consumes `self` and generates a JSON Schema for the given example value.
/// ///
/// If the value implements [`JsonSchema`](crate::JsonSchema), then prefer using the [`into_root_schema_for()!`](Self::into_root_schema_for()) /// If the value implements [`JsonSchema`](crate::JsonSchema), then prefer using the [`into_root_schema_for()!`](Self::into_root_schema_for())
/// function which will generally produce a more precise schema, particularly when the value contains any enums. /// function which will generally produce a more precise schema, particularly when the value contains any enums.
///
/// If the `Serialize` implementation of the value decides to fail, this will return an [`Err`].
pub fn into_root_schema_for_value<T: ?Sized + Serialize>( pub fn into_root_schema_for_value<T: ?Sized + Serialize>(
mut self, mut self,
value: &T, value: &T,
@ -513,7 +518,7 @@ fn json_pointer_mut<'a>(
Some(object) Some(object)
} }
/// A [Visitor](Visitor) which implements additional traits required to be included in a [SchemaSettings]. /// A [Visitor] which implements additional traits required to be included in a [SchemaSettings].
/// ///
/// You will rarely need to use this trait directly as it is automatically implemented for any type which implements all of: /// You will rarely need to use this trait directly as it is automatically implemented for any type which implements all of:
/// - [`Visitor`] /// - [`Visitor`]

View file

@ -11,7 +11,9 @@ mod macros;
/// outside of `schemars`, and should not be considered part of the public API. /// outside of `schemars`, and should not be considered part of the public API.
#[doc(hidden)] #[doc(hidden)]
pub mod _private; pub mod _private;
/// Types for generating JSON schemas.
pub mod gen; pub mod gen;
/// Types for recursively modifying JSON schemas.
pub mod visit; pub mod visit;
#[cfg(feature = "schemars_derive")] #[cfg(feature = "schemars_derive")]
@ -25,6 +27,7 @@ pub use schemars_derive::*;
#[doc(hidden)] #[doc(hidden)]
pub use serde_json as _serde_json; pub use serde_json as _serde_json;
pub use gen::SchemaGenerator;
pub use schema::Schema; pub use schema::Schema;
/// A type which can be described as a JSON Schema document. /// A type which can be described as a JSON Schema document.
@ -50,7 +53,7 @@ pub use schema::Schema;
/// you will need to determine an appropriate name and ID for the type. /// you will need to determine an appropriate name and ID for the type.
/// For non-generic types, the type name/path are suitable for this: /// For non-generic types, the type name/path are suitable for this:
/// ``` /// ```
/// use schemars::{gen::SchemaGenerator, Schema, JsonSchema}; /// use schemars::{SchemaGenerator, Schema, JsonSchema, json_schema};
/// use std::borrow::Cow; /// use std::borrow::Cow;
/// ///
/// struct NonGenericType; /// struct NonGenericType;
@ -67,7 +70,9 @@ pub use schema::Schema;
/// } /// }
/// ///
/// fn json_schema(_gen: &mut SchemaGenerator) -> Schema { /// fn json_schema(_gen: &mut SchemaGenerator) -> Schema {
/// todo!() /// json_schema!({
/// "foo": "bar"
/// })
/// } /// }
/// } /// }
/// ///
@ -76,7 +81,7 @@ pub use schema::Schema;
/// ///
/// But generic type parameters which may affect the generated schema should typically be included in the name/ID: /// But generic type parameters which may affect the generated schema should typically be included in the name/ID:
/// ``` /// ```
/// use schemars::{gen::SchemaGenerator, Schema, JsonSchema}; /// use schemars::{SchemaGenerator, Schema, JsonSchema, json_schema};
/// use std::{borrow::Cow, marker::PhantomData}; /// use std::{borrow::Cow, marker::PhantomData};
/// ///
/// struct GenericType<T>(PhantomData<T>); /// struct GenericType<T>(PhantomData<T>);
@ -95,7 +100,9 @@ pub use schema::Schema;
/// } /// }
/// ///
/// fn json_schema(_gen: &mut SchemaGenerator) -> Schema { /// fn json_schema(_gen: &mut SchemaGenerator) -> Schema {
/// todo!() /// json_schema!({
/// "foo": "bar"
/// })
/// } /// }
/// } /// }
/// ///
@ -126,7 +133,7 @@ pub trait JsonSchema {
/// If two types produce different schemas, then they **must** have different `schema_id()`s, /// If two types produce different schemas, then they **must** have different `schema_id()`s,
/// but two types that produce identical schemas should *ideally* have the same `schema_id()`. /// but two types that produce identical schemas should *ideally* have the same `schema_id()`.
/// ///
/// The default implementation returns the same value as `schema_name()`. /// The default implementation returns the same value as [`schema_name()`](JsonSchema::schema_name).
fn schema_id() -> Cow<'static, str> { fn schema_id() -> Cow<'static, str> {
Self::schema_name() Self::schema_name()
} }
@ -134,14 +141,14 @@ pub trait JsonSchema {
/// Generates a JSON Schema for this type. /// Generates a JSON Schema for this type.
/// ///
/// If the returned schema depends on any [non-inlined](JsonSchema::always_inline_schema) schemas, then this method will /// If the returned schema depends on any [non-inlined](JsonSchema::always_inline_schema) schemas, then this method will
/// add them to the [`SchemaGenerator`](gen::SchemaGenerator)'s schema definitions. /// add them to the [`SchemaGenerator`](SchemaGenerator)'s schema definitions.
/// ///
/// This should not return a `$ref` schema. /// This should not return a `$ref` schema.
fn json_schema(gen: &mut gen::SchemaGenerator) -> Schema; fn json_schema(gen: &mut SchemaGenerator) -> Schema;
// TODO document and bring into public API? // TODO document and bring into public API?
#[doc(hidden)] #[doc(hidden)]
fn _schemars_private_non_optional_json_schema(gen: &mut gen::SchemaGenerator) -> Schema { fn _schemars_private_non_optional_json_schema(gen: &mut SchemaGenerator) -> Schema {
Self::json_schema(gen) Self::json_schema(gen)
} }

View file

@ -17,11 +17,12 @@
#[macro_export] #[macro_export]
macro_rules! schema_for { macro_rules! schema_for {
($type:ty) => { ($type:ty) => {
$crate::gen::SchemaGenerator::default().into_root_schema_for::<$type>() $crate::SchemaGenerator::default().into_root_schema_for::<$type>()
}; };
} }
/// Generates a [`RootSchema`](crate::schema::RootSchema) for the given type using default settings. /// Generates a [`Schema`](crate::Schema) for the given type using default settings.
/// 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.
/// ///
/// The type must implement [`JsonSchema`](crate::JsonSchema). /// The type must implement [`JsonSchema`](crate::JsonSchema).
/// ///
@ -40,22 +41,23 @@ macro_rules! schema_for {
#[macro_export] #[macro_export]
macro_rules! schema_for { macro_rules! schema_for {
($type:ty) => { ($type:ty) => {
$crate::gen::SchemaGenerator::default().into_root_schema_for::<$type>() $crate::SchemaGenerator::default().into_root_schema_for::<$type>()
}; };
($_:expr) => { ($_:expr) => {
compile_error!("This argument to `schema_for!` is not a type - did you mean to use `schema_for_value!` instead?") compile_error!("This argument to `schema_for!` is not a type - did you mean to use `schema_for_value!` instead?")
}; };
} }
/// Generates a [`RootSchema`](crate::schema::RootSchema) for the given example value using default settings. /// Generates a [`Schema`](crate::Schema) for the given example value using default settings.
/// 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.
/// ///
/// The value must implement [`Serialize`](serde::Serialize). If the value also implements [`JsonSchema`](crate::JsonSchema), /// The value must implement [`Serialize`](serde::Serialize). If the value also implements [`JsonSchema`](crate::JsonSchema),
/// then prefer using the [`schema_for!`](schema_for) macro which will generally produce a more precise schema, /// then prefer using the [`schema_for!(Type)`](schema_for) macro which will generally produce a more precise schema,
/// particularly when the value contains any enums. /// particularly when the value contains any enums.
/// ///
/// If the `Serialize` implementation of the value decides to fail, this macro will panic. /// If the `Serialize` implementation of the value decides to fail, this macro will panic.
/// For a non-panicking alternative, create a [`SchemaGenerator`](crate::gen::SchemaGenerator) and use /// For a non-panicking alternative, create a [`SchemaGenerator`](crate::SchemaGenerator) and use
/// its [`into_root_schema_for_value`](crate::gen::SchemaGenerator::into_root_schema_for_value) method. /// its [`into_root_schema_for_value`](crate::SchemaGenerator::into_root_schema_for_value) method.
/// ///
/// # Example /// # Example
/// ``` /// ```
@ -71,13 +73,26 @@ macro_rules! schema_for {
#[macro_export] #[macro_export]
macro_rules! schema_for_value { macro_rules! schema_for_value {
($value:expr) => { ($value:expr) => {
$crate::gen::SchemaGenerator::default() $crate::SchemaGenerator::default()
.into_root_schema_for_value(&$value) .into_root_schema_for_value(&$value)
.unwrap() .unwrap()
}; };
} }
// TODO doc /// Construct a [`Schema`](crate::Schema) from a JSON literal. This can either be a JSON object, or a boolean (`true` or `false`).
///
/// You can interpolate variables or expressions into a JSON object using the same rules as the [`serde_json::json`] macro.
///
/// # Example
/// ```
/// use schemars::{Schema, json_schema};
///
/// let desc = "A helpful description.";
/// let my_schema: Schema = json_schema!({
/// "description": desc,
/// "type": ["object", "null"]
/// });
/// ```
#[macro_export] #[macro_export]
macro_rules! json_schema { macro_rules! json_schema {
( (

View file

@ -7,6 +7,54 @@ use serde::{Deserialize, Serialize};
use serde_json::{Map, Value}; use serde_json::{Map, Value};
/// A JSON Schema. /// A JSON Schema.
///
/// This wraps a JSON [`Value`] that must be either an [object](Value::Object) or a [bool](Value::Bool).
///
/// A custom JSON schema can be created using the [`json_schema!`](crate::json_schema) macro:
/// ```
/// use schemars::{Schema, json_schema};
///
/// let my_schema: Schema = json_schema!({
/// "type": ["object", "null"]
/// });
/// ```
///
/// Because a `Schema` is a thin wrapper around a `Value`, you can also use [`TryFrom::try_from`]/[`TryInto::try_into`] to create a `Schema` from an existing `Value`.
/// This operation is fallible, because only [objects](Value::Object) and [bools](Value::Bool) can be converted in this way.
/// ```
/// use schemars::{Schema, json_schema};
/// use serde_json::json;
///
/// let json_object = json!({"type": ["object", "null"]});
/// let object_schema: Schema = json_object.try_into().unwrap();
///
/// let json_bool = json!(true);
/// let bool_schema: Schema = json_bool.try_into().unwrap();
///
/// let json_string = json!("This is neither an object nor a bool!");
/// assert!(Schema::try_from(json_string).is_err());
///
/// // You can also convert a `&Value`/`&mut Value` to a `&Schema`/`&mut Schema` the same way:
///
/// let json_object = json!({"type": ["object", "null"]});
/// let object_schema_ref: &Schema = (&json_object).try_into().unwrap();
///
/// let mut json_object = json!({"type": ["object", "null"]});
/// let object_schema_mut: &mut Schema = (&mut json_object).try_into().unwrap();
///
/// ```
///
/// Similarly, you can use [`From`]/[`Into`] to (infallibly) create a `Schema` from an existing [`Map<String, Value>`] or [`bool`].
/// ```
/// use schemars::{Schema, json_schema};
/// use serde_json::{Map, json};
///
/// let mut map = Map::new();
/// map.insert("type".to_owned(), json!(["object", "null"]));
/// let object_schema: Schema = map.into();
///
/// let bool_schema: Schema = true.into();
/// ```
#[derive(Debug, Clone, PartialEq, RefCastCustom)] #[derive(Debug, Clone, PartialEq, RefCastCustom)]
#[repr(transparent)] #[repr(transparent)]
pub struct Schema(Value); pub struct Schema(Value);
@ -32,28 +80,32 @@ impl Serialize for Schema {
} }
impl Schema { impl Schema {
pub fn new() -> Self { /// Creates a new schema object with a single string property `"$ref"`.
Self(Value::Object(Map::new())) ///
} /// The given reference string should be a URI reference. This will usually be a JSON Pointer
/// in [URI Fragment representation](https://tools.ietf.org/html/rfc6901#section-6).
pub fn new_ref(reference: String) -> Self { pub fn new_ref(reference: String) -> Self {
let mut map = Map::new(); let mut map = Map::new();
map.insert("$ref".to_owned(), Value::String(reference)); map.insert("$ref".to_owned(), Value::String(reference));
Self(Value::Object(map)) Self(Value::Object(map))
} }
/// Borrows the `Schema`'s underlying JSON value.
pub fn as_value(&self) -> &Value { pub fn as_value(&self) -> &Value {
&self.0 &self.0
} }
/// If the `Schema`'s underlying JSON value is a bool, returns the bool value.
pub fn as_bool(&self) -> Option<bool> { pub fn as_bool(&self) -> Option<bool> {
self.0.as_bool() self.0.as_bool()
} }
/// If the `Schema`'s underlying JSON value is an object, borrows the object as a `Map` of properties.
pub fn as_object(&self) -> Option<&Map<String, Value>> { pub fn as_object(&self) -> Option<&Map<String, Value>> {
self.0.as_object() self.0.as_object()
} }
/// If the `Schema`'s underlying JSON value is an object, mutably borrows the object as a `Map` of properties.
pub fn as_object_mut(&mut self) -> Option<&mut Map<String, Value>> { pub fn as_object_mut(&mut self) -> Option<&mut Map<String, Value>> {
self.0.as_object_mut() self.0.as_object_mut()
} }
@ -66,10 +118,15 @@ impl Schema {
} }
} }
/// Returns the `Schema`'s underlying JSON value.
pub fn to_value(self) -> Value { pub fn to_value(self) -> Value {
self.0 self.0
} }
/// Converts the `Schema` (if it wraps a bool value) into an equivalent object schema. Then mutably borrows the object as a `Map` of properties.
///
/// `true` is transformed into an empty schema `{}`, which successfully validates against all possible values.
/// `false` is transformed into the schema `{"not": {}}`, which does not successfully validate against any value.
pub fn ensure_object(&mut self) -> &mut Map<String, Value> { pub fn ensure_object(&mut self) -> &mut Map<String, Value> {
if let Some(b) = self.as_bool() { if let Some(b) = self.as_bool() {
let mut map = Map::new(); let mut map = Map::new();

View file

@ -1,5 +1,4 @@
use crate::gen::SchemaGenerator; use crate::{json_schema, JsonSchema, Schema, SchemaGenerator};
use crate::{json_schema, JsonSchema, Schema};
use serde_json::{Error, Map, Value}; use serde_json::{Error, Map, Value};
use std::fmt::Display; use std::fmt::Display;

View file

@ -2,7 +2,7 @@ mod util;
use schemars::JsonSchema; use schemars::JsonSchema;
use util::*; use util::*;
fn schema_fn(gen: &mut schemars::gen::SchemaGenerator) -> schemars::Schema { fn schema_fn(gen: &mut schemars::SchemaGenerator) -> schemars::Schema {
<bool>::json_schema(gen) <bool>::json_schema(gen)
} }

View file

@ -2,7 +2,7 @@ mod util;
use schemars::JsonSchema; use schemars::JsonSchema;
use util::*; use util::*;
fn schema_fn(gen: &mut schemars::gen::SchemaGenerator) -> schemars::Schema { fn schema_fn(gen: &mut schemars::SchemaGenerator) -> schemars::Schema {
<bool>::json_schema(gen) <bool>::json_schema(gen)
} }

View file

@ -68,11 +68,11 @@ fn derive_json_schema(mut input: syn::DeriveInput, repr: bool) -> syn::Result<To
<#ty as schemars::JsonSchema>::schema_id() <#ty as schemars::JsonSchema>::schema_id()
} }
fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::Schema { fn json_schema(gen: &mut schemars::SchemaGenerator) -> schemars::Schema {
<#ty as schemars::JsonSchema>::json_schema(gen) <#ty as schemars::JsonSchema>::json_schema(gen)
} }
fn _schemars_private_non_optional_json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::Schema { fn _schemars_private_non_optional_json_schema(gen: &mut schemars::SchemaGenerator) -> schemars::Schema {
<#ty as schemars::JsonSchema>::_schemars_private_non_optional_json_schema(gen) <#ty as schemars::JsonSchema>::_schemars_private_non_optional_json_schema(gen)
} }
@ -186,7 +186,7 @@ fn derive_json_schema(mut input: syn::DeriveInput, repr: bool) -> syn::Result<To
#schema_id #schema_id
} }
fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::Schema { fn json_schema(gen: &mut schemars::SchemaGenerator) -> schemars::Schema {
#schema_expr #schema_expr
} }
}; };

View file

@ -127,7 +127,7 @@ fn type_for_schema(with_attr: &WithAttr) -> (syn::Type, Option<TokenStream>) {
)) ))
} }
fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::Schema { fn json_schema(gen: &mut schemars::SchemaGenerator) -> schemars::Schema {
#fun(gen) #fun(gen)
} }
} }