Replace is_referenceable()
with always_inline_schema()
This commit is contained in:
parent
1aaa162e0b
commit
f8b56cb455
22 changed files with 53 additions and 52 deletions
|
@ -63,14 +63,14 @@ This function creates the JSON schema itself. The `gen` argument can be used to
|
|||
|
||||
`json_schema` should not return a `$ref` schema.
|
||||
|
||||
## is_referenceable (optional)
|
||||
## always_inline_schema (optional)
|
||||
|
||||
```rust
|
||||
fn is_referenceable() -> bool;
|
||||
fn always_inline_schema() -> bool;
|
||||
```
|
||||
|
||||
If this function returns `true`, then Schemars can re-use the generate schema where possible by adding it to the root schema's `definitions` and having other schemas reference it using the `$ref` keyword. This can greatly simplify schemas that include a particular type multiple times, especially if that type's schema is fairly complex.
|
||||
If this function returns `false`, then Schemars can re-use the generate schema where possible by adding it to the root schema's `definitions` and having other schemas reference it using the `$ref` keyword. This can greatly simplify schemas that include a particular type multiple times, especially if that type's schema is fairly complex.
|
||||
|
||||
Generally, this should return `false` for types with simple schemas (such as primitives). For more complex types, it should return `true`. For recursive types, this **must** return `true` to prevent infinite cycles when generating schemas.
|
||||
Generally, this should return `true` for types with simple schemas (such as primitives). For more complex types, it should return `false`. For recursive types, this **must** return `false` to prevent infinite cycles when generating schemas.
|
||||
|
||||
The default implementation of this function returns `true` to reduce the chance of someone inadvertently causing infinite cycles with recursive types.
|
||||
The default implementation of this function returns `false` to reduce the chance of someone inadvertently causing infinite cycles with recursive types.
|
||||
|
|
|
@ -216,14 +216,14 @@ impl SchemaGenerator {
|
|||
|
||||
/// Generates a JSON Schema for the type `T`, and returns either the schema itself or a `$ref` schema referencing `T`'s schema.
|
||||
///
|
||||
/// If `T` is [referenceable](JsonSchema::is_referenceable), this will add `T`'s schema to this generator's definitions, and
|
||||
/// If `T` is not [inlined](JsonSchema::always_inline_schema), this will add `T`'s schema to this generator's definitions, and
|
||||
/// return a `$ref` schema referencing that schema. Otherwise, this method behaves identically to [`JsonSchema::json_schema`].
|
||||
///
|
||||
/// If `T`'s schema depends on any [referenceable](JsonSchema::is_referenceable) 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.
|
||||
pub fn subschema_for<T: ?Sized + JsonSchema>(&mut self) -> Schema {
|
||||
let id = T::schema_id();
|
||||
let return_ref = T::is_referenceable()
|
||||
let return_ref = !T::always_inline_schema()
|
||||
&& (!self.settings.inline_subschemas || self.pending_schema_ids.contains(&id));
|
||||
|
||||
if return_ref {
|
||||
|
@ -270,7 +270,7 @@ impl SchemaGenerator {
|
|||
self.definitions.insert(name.into(), schema.to_value());
|
||||
}
|
||||
|
||||
/// Borrows the collection of all [referenceable](JsonSchema::is_referenceable) schemas that have been generated.
|
||||
/// Borrows the collection of all [non-inlined](JsonSchema::always_inline_schema) schemas that have been generated.
|
||||
///
|
||||
/// The keys of the returned `Map` are the [schema names](JsonSchema::schema_name), and the values are the schemas
|
||||
/// themselves.
|
||||
|
@ -278,7 +278,7 @@ impl SchemaGenerator {
|
|||
&self.definitions
|
||||
}
|
||||
|
||||
/// Mutably borrows the collection of all [referenceable](JsonSchema::is_referenceable) schemas that have been generated.
|
||||
/// Mutably borrows the collection of all [non-inlined](JsonSchema::always_inline_schema) schemas that have been generated.
|
||||
///
|
||||
/// The keys of the returned `Map` are the [schema names](JsonSchema::schema_name), and the values are the schemas
|
||||
/// themselves.
|
||||
|
@ -286,7 +286,7 @@ impl SchemaGenerator {
|
|||
&mut self.definitions
|
||||
}
|
||||
|
||||
/// Returns the collection of all [referenceable](JsonSchema::is_referenceable) 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.
|
||||
///
|
||||
/// The keys of the returned `Map` are the [schema names](JsonSchema::schema_name), and the values are the schemas
|
||||
|
@ -302,7 +302,7 @@ impl SchemaGenerator {
|
|||
|
||||
/// Generates a root JSON Schema for the type `T`.
|
||||
///
|
||||
/// If `T`'s schema depends on any [referenceable](JsonSchema::is_referenceable) 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
|
||||
/// [`definitions`](../schema/struct.Metadata.html#structfield.definitions)
|
||||
pub fn root_schema_for<T: ?Sized + JsonSchema>(&mut self) -> Schema {
|
||||
|
@ -326,7 +326,7 @@ impl SchemaGenerator {
|
|||
|
||||
/// Consumes `self` and generates a root JSON Schema for the type `T`.
|
||||
///
|
||||
/// If `T`'s schema depends on any [referenceable](JsonSchema::is_referenceable) 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)
|
||||
pub fn into_root_schema_for<T: ?Sized + JsonSchema>(mut self) -> Schema {
|
||||
let mut schema = self.json_schema_internal::<T>(T::schema_id());
|
||||
|
|
|
@ -4,7 +4,7 @@ use std::borrow::Cow;
|
|||
|
||||
// Does not require T: JsonSchema.
|
||||
impl<T> JsonSchema for [T; 0] {
|
||||
no_ref_schema!();
|
||||
always_inline!();
|
||||
|
||||
fn schema_name() -> Cow<'static, str> {
|
||||
"EmptyArray".into()
|
||||
|
@ -26,7 +26,7 @@ macro_rules! array_impls {
|
|||
($($len:tt)+) => {
|
||||
$(
|
||||
impl<T: JsonSchema> JsonSchema for [T; $len] {
|
||||
no_ref_schema!();
|
||||
always_inline!();
|
||||
|
||||
fn schema_name() -> Cow<'static, str> {
|
||||
format!("Array_size_{}_of_{}", $len, T::schema_name()).into()
|
||||
|
|
|
@ -10,7 +10,7 @@ impl<T, const CAP: usize> JsonSchema for ArrayVec<T, CAP>
|
|||
where
|
||||
T: JsonSchema,
|
||||
{
|
||||
no_ref_schema!();
|
||||
always_inline!();
|
||||
|
||||
fn schema_name() -> std::borrow::Cow<'static, str> {
|
||||
format!("Array_up_to_size_{}_of_{}", CAP, T::schema_name()).into()
|
||||
|
|
|
@ -4,7 +4,7 @@ use chrono04::prelude::*;
|
|||
use std::borrow::Cow;
|
||||
|
||||
impl JsonSchema for Weekday {
|
||||
no_ref_schema!();
|
||||
always_inline!();
|
||||
|
||||
fn schema_name() -> Cow<'static, str> {
|
||||
"Weekday".into()
|
||||
|
@ -36,7 +36,7 @@ macro_rules! formatted_string_impl {
|
|||
};
|
||||
($ty:ident, $format:literal, $($desc:tt)+) => {
|
||||
impl $($desc)+ {
|
||||
no_ref_schema!();
|
||||
always_inline!();
|
||||
|
||||
fn schema_name() -> Cow<'static, str> {
|
||||
stringify!($ty).into()
|
||||
|
|
|
@ -5,7 +5,7 @@ use std::borrow::Cow;
|
|||
use std::ops::{Bound, Range, RangeInclusive};
|
||||
|
||||
impl<T: JsonSchema> JsonSchema for Option<T> {
|
||||
no_ref_schema!();
|
||||
always_inline!();
|
||||
|
||||
fn schema_name() -> Cow<'static, str> {
|
||||
format!("Nullable_{}", T::schema_name()).into()
|
||||
|
|
|
@ -5,7 +5,7 @@ use std::borrow::Cow;
|
|||
macro_rules! decimal_impl {
|
||||
($type:ty) => {
|
||||
impl JsonSchema for $type {
|
||||
no_ref_schema!();
|
||||
always_inline!();
|
||||
|
||||
fn schema_name() -> Cow<'static, str> {
|
||||
"Decimal".into()
|
||||
|
|
|
@ -4,7 +4,7 @@ use either1::Either;
|
|||
use std::borrow::Cow;
|
||||
|
||||
impl<L: JsonSchema, R: JsonSchema> JsonSchema for Either<L, R> {
|
||||
no_ref_schema!();
|
||||
always_inline!();
|
||||
|
||||
fn schema_name() -> Cow<'static, str> {
|
||||
format!("Either_{}_or_{}", L::schema_name(), R::schema_name()).into()
|
||||
|
|
|
@ -8,7 +8,7 @@ macro_rules! map_impl {
|
|||
where
|
||||
V: JsonSchema,
|
||||
{
|
||||
no_ref_schema!();
|
||||
always_inline!();
|
||||
|
||||
fn schema_name() -> Cow<'static, str> {
|
||||
format!("Map_of_{}", V::schema_name()).into()
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
macro_rules! no_ref_schema {
|
||||
macro_rules! always_inline {
|
||||
() => {
|
||||
fn is_referenceable() -> bool {
|
||||
false
|
||||
fn always_inline_schema() -> bool {
|
||||
true
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -9,8 +9,8 @@ macro_rules! no_ref_schema {
|
|||
macro_rules! forward_impl {
|
||||
(($($impl:tt)+) => $target:ty) => {
|
||||
impl $($impl)+ {
|
||||
fn is_referenceable() -> bool {
|
||||
<$target>::is_referenceable()
|
||||
fn always_inline_schema() -> bool {
|
||||
<$target>::always_inline_schema()
|
||||
}
|
||||
|
||||
fn schema_name() -> std::borrow::Cow<'static, str> {
|
||||
|
|
|
@ -6,7 +6,7 @@ use std::num::*;
|
|||
macro_rules! nonzero_unsigned_impl {
|
||||
($type:ty => $primitive:ty) => {
|
||||
impl JsonSchema for $type {
|
||||
no_ref_schema!();
|
||||
always_inline!();
|
||||
|
||||
fn schema_name() -> Cow<'static, str> {
|
||||
stringify!($type).into()
|
||||
|
|
|
@ -7,7 +7,7 @@ use std::num::*;
|
|||
macro_rules! nonzero_unsigned_impl {
|
||||
($type:ty => $primitive:ty) => {
|
||||
impl JsonSchema for $type {
|
||||
no_ref_schema!();
|
||||
always_inline!();
|
||||
|
||||
fn schema_name() -> Cow<'static, str> {
|
||||
stringify!($type).into()
|
||||
|
|
|
@ -7,7 +7,7 @@ use std::path::{Path, PathBuf};
|
|||
macro_rules! simple_impl {
|
||||
($type:ty => $instance_type:literal) => {
|
||||
impl JsonSchema for $type {
|
||||
no_ref_schema!();
|
||||
always_inline!();
|
||||
|
||||
fn schema_name() -> Cow<'static, str> {
|
||||
$instance_type.into()
|
||||
|
@ -22,7 +22,7 @@ macro_rules! simple_impl {
|
|||
};
|
||||
($type:ty => $instance_type:literal, $format:literal) => {
|
||||
impl JsonSchema for $type {
|
||||
no_ref_schema!();
|
||||
always_inline!();
|
||||
|
||||
fn schema_name() -> Cow<'static, str> {
|
||||
$format.into()
|
||||
|
@ -65,7 +65,7 @@ simple_impl!(SocketAddrV6 => "string");
|
|||
macro_rules! unsigned_impl {
|
||||
($type:ty => $instance_type:literal, $format:literal) => {
|
||||
impl JsonSchema for $type {
|
||||
no_ref_schema!();
|
||||
always_inline!();
|
||||
|
||||
fn schema_name() -> Cow<'static, str> {
|
||||
$format.into()
|
||||
|
@ -90,7 +90,7 @@ unsigned_impl!(u128 => "integer", "uint128");
|
|||
unsigned_impl!(usize => "integer", "uint");
|
||||
|
||||
impl JsonSchema for char {
|
||||
no_ref_schema!();
|
||||
always_inline!();
|
||||
|
||||
fn schema_name() -> Cow<'static, str> {
|
||||
"Character".into()
|
||||
|
|
|
@ -4,7 +4,7 @@ use semver1::Version;
|
|||
use std::borrow::Cow;
|
||||
|
||||
impl JsonSchema for Version {
|
||||
no_ref_schema!();
|
||||
always_inline!();
|
||||
|
||||
fn schema_name() -> Cow<'static, str> {
|
||||
"Version".into()
|
||||
|
|
|
@ -8,7 +8,7 @@ macro_rules! seq_impl {
|
|||
where
|
||||
T: JsonSchema,
|
||||
{
|
||||
no_ref_schema!();
|
||||
always_inline!();
|
||||
|
||||
fn schema_name() -> Cow<'static, str> {
|
||||
format!("Array_of_{}", T::schema_name()).into()
|
||||
|
@ -34,7 +34,7 @@ macro_rules! set_impl {
|
|||
where
|
||||
T: JsonSchema,
|
||||
{
|
||||
no_ref_schema!();
|
||||
always_inline!();
|
||||
|
||||
fn schema_name() -> Cow<'static, str> {
|
||||
format!("Set_of_{}", T::schema_name()).into()
|
||||
|
|
|
@ -5,7 +5,7 @@ use std::borrow::Cow;
|
|||
use std::collections::BTreeMap;
|
||||
|
||||
impl JsonSchema for Value {
|
||||
no_ref_schema!();
|
||||
always_inline!();
|
||||
|
||||
fn schema_name() -> Cow<'static, str> {
|
||||
"AnyValue".into()
|
||||
|
@ -19,7 +19,7 @@ impl JsonSchema for Value {
|
|||
forward_impl!(Map<String, Value> => BTreeMap<String, Value>);
|
||||
|
||||
impl JsonSchema for Number {
|
||||
no_ref_schema!();
|
||||
always_inline!();
|
||||
|
||||
fn schema_name() -> Cow<'static, str> {
|
||||
"Number".into()
|
||||
|
|
|
@ -6,7 +6,7 @@ macro_rules! tuple_impls {
|
|||
($($len:expr => ($($name:ident)+))+) => {
|
||||
$(
|
||||
impl<$($name: JsonSchema),+> JsonSchema for ($($name,)+) {
|
||||
no_ref_schema!();
|
||||
always_inline!();
|
||||
|
||||
fn schema_name() -> Cow<'static, str> {
|
||||
let mut name = "Tuple_of_".to_owned();
|
||||
|
|
|
@ -4,7 +4,7 @@ use std::borrow::Cow;
|
|||
use url2::Url;
|
||||
|
||||
impl JsonSchema for Url {
|
||||
no_ref_schema!();
|
||||
always_inline!();
|
||||
|
||||
fn schema_name() -> Cow<'static, str> {
|
||||
"Url".into()
|
||||
|
|
|
@ -4,7 +4,7 @@ use std::borrow::Cow;
|
|||
use uuid1::Uuid;
|
||||
|
||||
impl JsonSchema for Uuid {
|
||||
no_ref_schema!();
|
||||
always_inline!();
|
||||
|
||||
fn schema_name() -> Cow<'static, str> {
|
||||
"Uuid".into()
|
||||
|
|
|
@ -104,14 +104,15 @@ pub use schema::Schema;
|
|||
///
|
||||
|
||||
pub trait JsonSchema {
|
||||
/// Whether JSON Schemas generated for this type should be re-used where possible using the `$ref` keyword.
|
||||
/// Whether JSON Schemas generated for this type should be included directly in parent schemas, rather than being
|
||||
/// re-used where possible using the `$ref` keyword.
|
||||
///
|
||||
/// For trivial types (such as primitives), this should return `false`. For more complex types, it should return `true`.
|
||||
/// For recursive types, this **must** return `true` to prevent infinite cycles when generating schemas.
|
||||
/// For trivial types (such as primitives), this should return `true`. For more complex types, it should return `false`.
|
||||
/// For recursive types, this **must** return `false` to prevent infinite cycles when generating schemas.
|
||||
///
|
||||
/// By default, this returns `true`.
|
||||
fn is_referenceable() -> bool {
|
||||
true
|
||||
/// By default, this returns `false`.
|
||||
fn always_inline_schema() -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
/// The name of the generated JSON Schema.
|
||||
|
@ -132,7 +133,7 @@ pub trait JsonSchema {
|
|||
|
||||
/// Generates a JSON Schema for this type.
|
||||
///
|
||||
/// If the returned schema depends on any [referenceable](JsonSchema::is_referenceable) 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.
|
||||
///
|
||||
/// This should not return a `$ref` schema.
|
||||
|
|
|
@ -56,8 +56,8 @@ fn derive_json_schema(mut input: syn::DeriveInput, repr: bool) -> syn::Result<To
|
|||
|
||||
#[automatically_derived]
|
||||
impl #impl_generics schemars::JsonSchema for #type_name #ty_generics #where_clause {
|
||||
fn is_referenceable() -> bool {
|
||||
<#ty as schemars::JsonSchema>::is_referenceable()
|
||||
fn always_inline_schema() -> bool {
|
||||
<#ty as schemars::JsonSchema>::always_inline_schema()
|
||||
}
|
||||
|
||||
fn schema_name() -> std::borrow::Cow<'static, str> {
|
||||
|
|
|
@ -110,8 +110,8 @@ fn type_for_schema(with_attr: &WithAttr) -> (syn::Type, Option<TokenStream>) {
|
|||
struct #ty_name;
|
||||
|
||||
impl schemars::JsonSchema for #ty_name {
|
||||
fn is_referenceable() -> bool {
|
||||
false
|
||||
fn always_inline_schema() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn schema_name() -> std::borrow::Cow<'static, str> {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue