From 4c501990b14b9212378bbe3298961f946324e86c Mon Sep 17 00:00:00 2001 From: Graham Esau Date: Fri, 15 May 2020 17:42:37 +0100 Subject: [PATCH] Document `schema_with` attribute --- docs/1.1-attributes.md | 12 ++++++++++-- docs/_includes/examples/custom_serialization.rs | 14 ++++++++++++-- .../examples/custom_serialization.schema.json | 3 ++- docs/examples/7-custom_serialization.md | 2 +- schemars/examples/custom_serialization.rs | 14 ++++++++++++-- schemars/examples/custom_serialization.schema.json | 3 ++- 6 files changed, 39 insertions(+), 9 deletions(-) diff --git a/docs/1.1-attributes.md b/docs/1.1-attributes.md index 9b44aee..6ff7fee 100644 --- a/docs/1.1-attributes.md +++ b/docs/1.1-attributes.md @@ -30,6 +30,7 @@ Serde also allows setting `#[serde(...)]` attributes which change how types are - [`flatten`](#flatten) - [`with`](#with) 1. [Other Attributes](#other-attributes) + - [`schema_with`](#schema_with) - [Doc Comments (`doc`)](#doc) ## Supported Serde Attributes @@ -117,16 +118,23 @@ Serde docs: [field](https://serde.rs/field-attrs.html#flatten) `#[serde(with = "Type")]` / `#[schemars(with = "Type")]` -Set on a field to generate this field's schema as the given type instead of the field's actual type. Serde allows the `with` attribute to refer to any module path, but Schemars requires this to be an actual type which implements `JsonSchema`. +Set on a variant or field to generate its schema as the given type instead of its actual type. Serde allows the `with` attribute to refer to any module path, but Schemars requires this to be an actual type which implements `JsonSchema`. If the given type has any required generic type parameters, then they must all be explicitly specified in this attribute. Serde frequently allows you to omit them as it can make use of type inference, but unfortunately this is not possible with Schemars. For example, `with = "Vec::"` will work, but `with = "Vec"` and `with = "Vec::<_>"` will not. -Serde docs: [field](https://serde.rs/field-attrs.html#with) +Serde docs: [variant](https://serde.rs/variant-attrs.html#with) / [field](https://serde.rs/field-attrs.html#with) ## Other Attributes +

+ +`#[schemars(schema_with = "some::function")]` +

+ +Set on a variant or field to generate this field's schema using the given function. This function must be callable as `fn(&mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema`. +

Doc Comments (`#[doc = "..."]`) diff --git a/docs/_includes/examples/custom_serialization.rs b/docs/_includes/examples/custom_serialization.rs index 9429bc3..53c78fa 100644 --- a/docs/_includes/examples/custom_serialization.rs +++ b/docs/_includes/examples/custom_serialization.rs @@ -1,4 +1,5 @@ -use schemars::{schema_for, JsonSchema}; +use schemars::schema::{Schema, SchemaObject}; +use schemars::{gen::SchemaGenerator, schema_for, JsonSchema}; use serde::{Deserialize, Serialize}; // `int_as_string` and `bool_as_string` use the schema for `String`. @@ -7,15 +8,24 @@ pub struct MyStruct { #[serde(default = "eight", with = "as_string")] #[schemars(with = "String")] pub int_as_string: i32, + #[serde(default = "eight")] pub int_normal: i32, + #[serde(default, with = "as_string")] - #[schemars(with = "String")] + #[schemars(schema_with = "make_custom_schema")] pub bool_as_string: bool, + #[serde(default)] pub bool_normal: bool, } +fn make_custom_schema(gen: &mut SchemaGenerator) -> Schema { + let mut schema: SchemaObject = ::json_schema(gen).into(); + schema.format = Some("boolean".to_owned()); + schema.into() +} + fn eight() -> i32 { 8 } diff --git a/docs/_includes/examples/custom_serialization.schema.json b/docs/_includes/examples/custom_serialization.schema.json index 017a143..42fda99 100644 --- a/docs/_includes/examples/custom_serialization.schema.json +++ b/docs/_includes/examples/custom_serialization.schema.json @@ -5,7 +5,8 @@ "properties": { "bool_as_string": { "default": "false", - "type": "string" + "type": "string", + "format": "boolean" }, "bool_normal": { "default": false, diff --git a/docs/examples/7-custom_serialization.md b/docs/examples/7-custom_serialization.md index 7005262..8caa930 100644 --- a/docs/examples/7-custom_serialization.md +++ b/docs/examples/7-custom_serialization.md @@ -13,7 +13,7 @@ summary: >- Serde allows you to change how a field is (de)serialized by setting a [`#[serde(with = "path")]`](https://serde.rs/field-attrs.html#with) attribute, where `$path::serialize` and `$path::deserialize` must be functions with the correct signature. Schemars supports the same attribute, but `path` must be a type implementing `JsonSchema`. -In order to derive `JsonSchema` on a type which includes a `#[serde(with = "path")]` attribute where `path` is not a type implementing `JsonSchema`, you'll need to override it with a suitable `#[schemars(with = "Type")]` attribute. +In order to derive `JsonSchema` on a type which includes a `#[serde(with = "path")]` attribute where `path` is not a type implementing `JsonSchema`, you'll need to override it with a suitable `#[schemars(with = "Type")]` or `#[schemars(schema_with = "path")]` attribute. {% include example.md name="custom_serialization" %} diff --git a/schemars/examples/custom_serialization.rs b/schemars/examples/custom_serialization.rs index 9429bc3..53c78fa 100644 --- a/schemars/examples/custom_serialization.rs +++ b/schemars/examples/custom_serialization.rs @@ -1,4 +1,5 @@ -use schemars::{schema_for, JsonSchema}; +use schemars::schema::{Schema, SchemaObject}; +use schemars::{gen::SchemaGenerator, schema_for, JsonSchema}; use serde::{Deserialize, Serialize}; // `int_as_string` and `bool_as_string` use the schema for `String`. @@ -7,15 +8,24 @@ pub struct MyStruct { #[serde(default = "eight", with = "as_string")] #[schemars(with = "String")] pub int_as_string: i32, + #[serde(default = "eight")] pub int_normal: i32, + #[serde(default, with = "as_string")] - #[schemars(with = "String")] + #[schemars(schema_with = "make_custom_schema")] pub bool_as_string: bool, + #[serde(default)] pub bool_normal: bool, } +fn make_custom_schema(gen: &mut SchemaGenerator) -> Schema { + let mut schema: SchemaObject = ::json_schema(gen).into(); + schema.format = Some("boolean".to_owned()); + schema.into() +} + fn eight() -> i32 { 8 } diff --git a/schemars/examples/custom_serialization.schema.json b/schemars/examples/custom_serialization.schema.json index 017a143..42fda99 100644 --- a/schemars/examples/custom_serialization.schema.json +++ b/schemars/examples/custom_serialization.schema.json @@ -5,7 +5,8 @@ "properties": { "bool_as_string": { "default": "false", - "type": "string" + "type": "string", + "format": "boolean" }, "bool_normal": { "default": false,