diff --git a/CHANGELOG.md b/CHANGELOG.md index 7abb93d..8330008 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,8 +14,8 @@ - `SchemaSettings` no longer implements `PartialEq` - `SchemaGenerator::into_definitions()` - this has been superseded by `SchemaGenerator::take_definitions()` -### Changed (**BREAKING CHANGES**): -- Minimum supported rust version is now 1.36.0 +### Changed: +- **BREAKING CHANGE** Minimum supported rust version is now 1.36.0 ### Fixed: - **BREAKING CHANGE** unknown items in `#[schemars(...)]` attributes now cause a compilation error (https://github.com/GREsau/schemars/issues/18) diff --git a/schemars/src/gen.rs b/schemars/src/gen.rs index 04992ab..de35268 100644 --- a/schemars/src/gen.rs +++ b/schemars/src/gen.rs @@ -1,3 +1,12 @@ +/*! +JSON Schema generator and settings. + +This module is useful if you want more control over how the schema generated then the [`schema_for!`] macro gives you. +There are two main types in this module:two main types in this module: +* [`SchemaSettings`], which defines what JSON Schema features should be used when generating schemas (for example, how `Option`s should be represented). +* [`SchemaGenerator`], which manages the generation of a schema document. +*/ + use crate::flatten::Merge; use crate::schema::*; use crate::{visit::*, JsonSchema, Map}; @@ -29,7 +38,7 @@ pub struct SchemaSettings { /// Defaults to `"http://json-schema.org/draft-07/schema#"`. pub meta_schema: Option, /// A list of visitors that get applied to all generated root schemas. - pub visitors: Vec>, + pub visitors: Vec>, _hidden: (), } @@ -105,7 +114,7 @@ impl SchemaSettings { } /// Appends the given visitor to the list of [visitors](SchemaSettings::visitors) for these `SchemaSettings`. - pub fn with_visitor(mut self, visitor: impl Visitor + Debug + DynClone + 'static) -> Self { + pub fn with_visitor(mut self, visitor: impl Visitor + Debug + Clone + 'static) -> Self { self.visitors.push(Box::new(visitor)); self } @@ -225,7 +234,7 @@ impl SchemaGenerator { } /// Returns an iterator over the [visitors](SchemaSettings::visitors) being used by this `SchemaGenerator`. - pub fn visitors_mut(&mut self) -> impl Iterator { + pub fn visitors_mut(&mut self) -> impl Iterator { self.settings.visitors.iter_mut().map(|v| v.as_mut()) } @@ -336,31 +345,31 @@ impl SchemaGenerator { /// - [`Visitor`] /// - [`std::fmt::Debug`] /// - [`std::any::Any`] (implemented for all `'static` types) -/// - [`dyn_clone::DynClone`] (or [`std::clone::Clone`]) +/// - [`std::clone::Clone`] /// /// # Example /// ``` /// use schemars::visit::Visitor; -/// use schemars::gen::Visitor2; +/// use schemars::gen::GenVisitor; /// /// #[derive(Debug, Clone)] /// struct MyVisitor; /// /// impl Visitor for MyVisitor { } /// -/// let v: &dyn Visitor2 = &MyVisitor; -/// assert_eq!(v.as_any().is::(), true); +/// let v: &dyn GenVisitor = &MyVisitor; +/// assert!(v.as_any().is::()); /// ``` -pub trait Visitor2: Visitor + Debug + DynClone + Any { +pub trait GenVisitor: Visitor + Debug + DynClone + Any { /// Upcasts this visitor into an `Any`, which can be used to inspect and manipulate it as its concrete type. fn as_any(&self) -> &dyn Any; } -dyn_clone::clone_trait_object!(Visitor2); +dyn_clone::clone_trait_object!(GenVisitor); -impl Visitor2 for T +impl GenVisitor for T where - T: Visitor + Debug + DynClone + Any, + T: Visitor + Debug + Clone + Any, { fn as_any(&self) -> &dyn Any { self diff --git a/schemars/src/lib.rs b/schemars/src/lib.rs index c81f051..1af35f7 100644 --- a/schemars/src/lib.rs +++ b/schemars/src/lib.rs @@ -227,7 +227,8 @@ pub type Map = indexmap::IndexMap; pub type Set = std::collections::BTreeSet; /// A view into a single entry in a map, which may either be vacant or occupied. -/// This is constructed from the `entry` method on `BTreeMap` or `IndexMap` +// +/// This is constructed from the `entry` method on `BTreeMap` or `IndexMap`, /// depending on whether the `preserve_order` feature flag is set. #[cfg(not(feature = "preserve_order"))] pub type MapEntry<'a, K, V> = std::collections::btree_map::Entry<'a, K, V>; @@ -239,11 +240,8 @@ mod json_schema_impls; #[macro_use] mod macros; -/// JSON Schema generator and settings. pub mod gen; -/// JSON Schema types. pub mod schema; -/// TODO document pub mod visit; #[cfg(feature = "schemars_derive")] diff --git a/schemars/src/macros.rs b/schemars/src/macros.rs index ba2dc4b..226f2cc 100644 --- a/schemars/src/macros.rs +++ b/schemars/src/macros.rs @@ -1,6 +1,6 @@ -/// Generates a [`RootSchema`](schema::RootSchema) for the given type using default settings. +/// Generates a [`RootSchema`](crate::schema::RootSchema) for the given type using default settings. /// -/// The type must implement [`JsonSchema`]. +/// The type must implement [`JsonSchema`](crate::JsonSchema). /// /// # Example /// ``` diff --git a/schemars/src/schema.rs b/schemars/src/schema.rs index e1b606c..a4c6e32 100644 --- a/schemars/src/schema.rs +++ b/schemars/src/schema.rs @@ -1,3 +1,7 @@ +/*! +JSON Schema types. +*/ + #[cfg(feature = "impl_json_schema")] use crate as schemars; #[cfg(feature = "impl_json_schema")] diff --git a/schemars/src/visit.rs b/schemars/src/visit.rs index 30d7d2a..af595bd 100644 --- a/schemars/src/visit.rs +++ b/schemars/src/visit.rs @@ -1,37 +1,70 @@ +/*! +Contains the [`Visitor`] trait, used to recursively modify a constructed schema and its subschemas. + +Sometimes you may want to apply a change to a schema, as well as all schemas contained within it. +The easiest way to achieve this is by defining a type that implements [`Visitor`]. +All methods of `Visitor` have a default implementation that makes no change but recursively visits all subschemas. +When overriding one of these methods, you will *usually* want to still call this default implementation. + +# Example +To add a custom property to all schemas: +``` +use schemars::schema::SchemaObject; +use schemars::visit::{Visitor, visit_schema_object}; + +pub struct MyVisitor; + +impl Visitor for MyVisitor { + fn visit_schema_object(&mut self, schema: &mut SchemaObject) { + // First, make our change to this schema + schema.extensions.insert("my_property".to_string(), serde_json::json!("hello world")); + + // Then delegate to default implementation to visit any subschemas + visit_schema_object(self, schema); + } +} +``` +*/ use crate::schema::{RootSchema, Schema, SchemaObject, SingleOrVec}; -/// TODO document +/// Trait used to recursively modify a constructed schema and its subschemas. pub trait Visitor { - /// TODO document + /// Override this method to modify a [`RootSchema`] and (optionally) its subschemas. + /// + /// When overriding this method, you will usually want to call the [`visit_root_schema`] function to visit subschemas. fn visit_root_schema(&mut self, root: &mut RootSchema) { visit_root_schema(self, root) } - /// TODO document + /// Override this method to modify a [`Schema`] and (optionally) its subschemas. + /// + /// When overriding this method, you will usually want to call the [`visit_schema`] function to visit subschemas. fn visit_schema(&mut self, schema: &mut Schema) { visit_schema(self, schema) } - /// TODO document + /// Override this method to modify a [`SchemaObject`] and (optionally) its subschemas. + /// + /// When overriding this method, you will usually want to call the [`visit_schema_object`] function to visit subschemas. fn visit_schema_object(&mut self, schema: &mut SchemaObject) { visit_schema_object(self, schema) } } -/// TODO document +/// Visits all subschemas of the [`RootSchema`]. pub fn visit_root_schema(v: &mut V, root: &mut RootSchema) { v.visit_schema_object(&mut root.schema); visit_map_values(v, &mut root.definitions); } -/// TODO document +/// Visits all subschemas of the [`Schema`]. pub fn visit_schema(v: &mut V, schema: &mut Schema) { if let Schema::Object(schema) = schema { v.visit_schema_object(schema) } } -/// TODO document +/// Visits all subschemas of the [`SchemaObject`]. pub fn visit_schema_object(v: &mut V, schema: &mut SchemaObject) { if let Some(sub) = &mut schema.subschemas { visit_vec(v, &mut sub.all_of); @@ -89,10 +122,12 @@ fn visit_single_or_vec(v: &mut V, target: &mut Option