diff --git a/docs/0-migrating.md b/docs/0-migrating.md
index be79b360..fba59ddf 100644
--- a/docs/0-migrating.md
+++ b/docs/0-migrating.md
@@ -126,12 +126,12 @@ use schemars::Schema;
pub struct MyTransform;
impl Transform for MyTransform {
- fn transform(&mut self, schema: &mut Schema) {
+ fn transform(&mut self, schema: &mut Schema, generator: &mut SchemaGenerator) {
// First, make our change to this schema
schema.insert("my_property".to_string(), serde_json::json!("hello world"));
// Then apply the transform to any subschemas
- transform_subschemas(self, schema);
+ transform_subschemas(self, schema, generator);
}
}
@@ -139,32 +139,34 @@ let mut schema = schemars::schema_for!(str);
MyTransform.transform(&mut schema);
```
-Also, since `Transform` is now implemented for functions that take a single `&mut Schema` argument, you could also define it as a function instead of a struct:
+Also, since `Transform` is now implemented for functions that take a `&mut Schema` and `&mut SchemaGenerator` arguments, you could also define it as a function instead of a struct:
```rust
-fn my_transform(schema: &mut Schema) {
+fn my_transform(schema: &mut Schema, generator: &mut SchemaGenerator) {
// First, make our change to this schema
schema.insert("my_property".to_string(), serde_json::json!("hello world"));
// Then apply the transform to any subschemas
- transform_subschemas(&mut my_transform, schema);
+ transform_subschemas(&mut my_transform, schema, generator);
}
let mut schema = schemars::schema_for!(str);
-my_transform(&mut schema);
+let mut generator = SchemaGenerator::default();
+my_transform(&mut schema, &mut generator);
// Or equivalently:
-// my_transform.transform(&mut schema);
+// my_transform.transform(&mut schema, &mut generator);
```
Finally, you can also use the `RecursiveTransform` newtype to convert a non-recursive `Transform` (i.e. one that does not transform subschemas) into a recursive one, like so:
```rust
-fn my_transform2(schema: &mut Schema) {
+fn my_transform2(schema: &mut Schema, _generator: &mut SchemaGenerator) {
schema.insert("my_property".to_string(), serde_json::json!("hello world"));
}
let mut schema = schemars::schema_for!(str);
-RecursiveTransform(my_transform2).transform(&mut schema);
+let mut generator = SchemaGenerator::default();
+RecursiveTransform(my_transform2).transform(&mut schema, &mut generator);
```
## Changes to `#[validate(...)]` attributes
diff --git a/docs/_includes/attributes.md b/docs/_includes/attributes.md
index 1497b0f7..2391f0c9 100644
--- a/docs/_includes/attributes.md
+++ b/docs/_includes/attributes.md
@@ -348,10 +348,10 @@ struct Struct;
Set on a container, variant or field to run a `schemars::transform::Transform` against the generated schema. This can be specified multiple times to run multiple transforms.
-The `Transform` trait is implemented on functions with the signature `fn(&mut Schema) -> ()`, allowing you to do this:
+The `Transform` trait is implemented on functions with the signature `fn(&mut Schema, &mut SchemaGenerator) -> ()`, allowing you to do this:
```rust
-fn my_transform(schema: &mut Schema) {
+fn my_transform(schema: &mut Schema, generator: &mut SchemaGenerator) {
todo!()
}
@@ -360,6 +360,8 @@ fn my_transform(schema: &mut Schema) {
struct Struct;
```
+The transform function can use the `SchemaGenerator` to inject schemas in the `$defs` section.
+
Doc Comments (`#[doc = "..."]`)
diff --git a/docs/_includes/examples/schemars_attrs.rs b/docs/_includes/examples/schemars_attrs.rs
index 21c3bdcf..ca6d7026 100644
--- a/docs/_includes/examples/schemars_attrs.rs
+++ b/docs/_includes/examples/schemars_attrs.rs
@@ -24,7 +24,7 @@ pub enum MyEnum {
},
}
-fn remove_format(schema: &mut Schema) {
+fn remove_format(schema: &mut Schema, _generator: &mut SchemaGenerator) {
schema.remove("format");
}
diff --git a/schemars/examples/schemars_attrs.rs b/schemars/examples/schemars_attrs.rs
index 21c3bdcf..209a9172 100644
--- a/schemars/examples/schemars_attrs.rs
+++ b/schemars/examples/schemars_attrs.rs
@@ -1,4 +1,4 @@
-use schemars::{schema_for, JsonSchema, Schema};
+use schemars::{schema_for, JsonSchema, Schema, SchemaGenerator};
use serde::{Deserialize, Serialize};
#[derive(Deserialize, Serialize, JsonSchema)]
@@ -24,7 +24,7 @@ pub enum MyEnum {
},
}
-fn remove_format(schema: &mut Schema) {
+fn remove_format(schema: &mut Schema, _generator: &mut SchemaGenerator) {
schema.remove("format");
}
diff --git a/schemars/src/_private/mod.rs b/schemars/src/_private/mod.rs
index aa5c6fe5..9088c19d 100644
--- a/schemars/src/_private/mod.rs
+++ b/schemars/src/_private/mod.rs
@@ -29,7 +29,7 @@ pub fn json_schema_for_internally_tagged_enum_newtype_variant(
// Always allow aditional/unevaluated properties, because the outer struct determines
// whether it denies unknown fields.
- AllowUnknownProperties::default().transform(&mut schema);
+ AllowUnknownProperties::default().transform(&mut schema, generator);
schema
}
@@ -69,7 +69,7 @@ struct AllowUnknownProperties {
}
impl Transform for AllowUnknownProperties {
- fn transform(&mut self, schema: &mut Schema) {
+ fn transform(&mut self, schema: &mut Schema, generator: &mut SchemaGenerator) {
if schema.get("additionalProperties").and_then(Value::as_bool) == Some(false) {
schema.remove("additionalProperties");
self.did_modify = true;
@@ -79,7 +79,7 @@ impl Transform for AllowUnknownProperties {
self.did_modify = true;
}
- transform_immediate_subschemas(self, schema);
+ transform_immediate_subschemas(self, schema, generator);
}
}
diff --git a/schemars/src/generate.rs b/schemars/src/generate.rs
index 498d3b47..785e853a 100644
--- a/schemars/src/generate.rs
+++ b/schemars/src/generate.rs
@@ -368,6 +368,21 @@ impl SchemaGenerator {
self.settings.transforms.iter_mut().map(Box::as_mut)
}
+ /// Returns an iterator over the [transforms](SchemaSettings::transforms) being used by this
+ /// `SchemaGenerator`.
+ fn take_transforms(&mut self) -> Vec> {
+ core::mem::take(&mut self.settings.transforms)
+ }
+
+ /// Returns an iterator over the [transforms](SchemaSettings::transforms) being used by this
+ /// `SchemaGenerator`.
+ fn set_transforms(
+ &mut self,
+ transforms: Vec>,
+ ) -> Vec> {
+ core::mem::replace(&mut self.settings.transforms, transforms)
+ }
+
/// Generates a JSON Schema for the type `T`.
///
/// If `T`'s schema depends on any [non-inlined](JsonSchema::always_inline_schema) schemas, then
@@ -538,9 +553,11 @@ impl SchemaGenerator {
}
fn apply_transforms(&mut self, schema: &mut Schema) {
- for transform in self.transforms_mut() {
- transform.transform(schema);
+ let mut transforms = self.take_transforms();
+ for transform in &mut transforms {
+ transform.transform(schema, self);
}
+ self.set_transforms(transforms);
}
/// Returns `self.settings.definitions_path` as a plain JSON pointer to the definitions object,
@@ -606,7 +623,7 @@ fn json_pointer_mut<'a>(
/// struct MyTransform;
///
/// impl Transform for MyTransform {
-/// fn transform(&mut self, schema: &mut schemars::Schema) {
+/// fn transform(&mut self, schema: &mut schemars::Schema, generator: &mut schemars::SchemaGenerator) {
/// todo!()
/// }
/// }
diff --git a/schemars/src/transform.rs b/schemars/src/transform.rs
index 7d24b5d6..68eaa35f 100644
--- a/schemars/src/transform.rs
+++ b/schemars/src/transform.rs
@@ -13,27 +13,29 @@ To make a transform recursive (i.e. apply it to subschemas), you have two option
To add a custom property to all object schemas:
```
-# use schemars::{Schema, json_schema};
+# use schemars::{Schema, json_schema, SchemaGenerator};
use schemars::transform::{Transform, transform_subschemas};
pub struct MyTransform;
impl Transform for MyTransform {
- fn transform(&mut self, schema: &mut Schema) {
+ fn transform(&mut self, schema: &mut Schema, generator: &mut SchemaGenerator) {
// First, make our change to this schema
schema.insert("my_property".to_string(), "hello world".into());
// Then apply the transform to any subschemas
- transform_subschemas(self, schema);
+ transform_subschemas(self, schema, generator);
}
}
+let mut generator = SchemaGenerator::default();
+
let mut schema = json_schema!({
"type": "array",
"items": {}
});
-MyTransform.transform(&mut schema);
+MyTransform.transform(&mut schema, &mut generator);
assert_eq!(
schema,
@@ -49,21 +51,23 @@ assert_eq!(
The same example with a `fn` transform:
```
-# use schemars::{Schema, json_schema};
+# use schemars::{Schema, json_schema, SchemaGenerator};
use schemars::transform::transform_subschemas;
-fn add_property(schema: &mut Schema) {
+fn add_property(schema: &mut Schema, generator: &mut SchemaGenerator) {
schema.insert("my_property".to_string(), "hello world".into());
- transform_subschemas(&mut add_property, schema)
+ transform_subschemas(&mut add_property, schema, generator)
}
+let mut generator = SchemaGenerator::default();
+
let mut schema = json_schema!({
"type": "array",
"items": {}
});
-add_property(&mut schema);
+add_property(&mut schema, &mut generator);
assert_eq!(
schema,
@@ -79,10 +83,10 @@ assert_eq!(
And the same example using a closure wrapped in a `RecursiveTransform`:
```
-# use schemars::{Schema, json_schema};
+# use schemars::{Schema, json_schema, SchemaGenerator};
use schemars::transform::{Transform, RecursiveTransform};
-let mut transform = RecursiveTransform(|schema: &mut Schema| {
+let mut transform = RecursiveTransform(|schema: &mut Schema, _: &mut SchemaGenerator| {
schema.insert("my_property".to_string(), "hello world".into());
});
@@ -91,7 +95,9 @@ let mut schema = json_schema!({
"items": {}
});
-transform.transform(&mut schema);
+let mut generator = SchemaGenerator::default();
+
+transform.transform(&mut schema, &mut generator);
assert_eq!(
schema,
@@ -106,8 +112,8 @@ assert_eq!(
```
*/
-use crate::Schema;
use crate::_alloc_prelude::*;
+use crate::{Schema, SchemaGenerator};
use alloc::collections::BTreeSet;
use serde_json::{json, Map, Value};
@@ -119,7 +125,7 @@ pub trait Transform {
///
/// When overriding this method, you may want to call the [`transform_subschemas`] function to
/// also transform any subschemas.
- fn transform(&mut self, schema: &mut Schema);
+ fn transform(&mut self, schema: &mut Schema, generator: &mut SchemaGenerator);
// Not public API
// Hack to enable implementing Debug on Box even though closures don't
@@ -132,15 +138,19 @@ pub trait Transform {
impl Transform for F
where
- F: FnMut(&mut Schema),
+ F: FnMut(&mut Schema, &mut SchemaGenerator),
{
- fn transform(&mut self, schema: &mut Schema) {
- self(schema);
+ fn transform(&mut self, schema: &mut Schema, generator: &mut SchemaGenerator) {
+ self(schema, generator);
}
}
/// Applies the given [`Transform`] to all direct subschemas of the [`Schema`].
-pub fn transform_subschemas(t: &mut T, schema: &mut Schema) {
+pub fn transform_subschemas(
+ t: &mut T,
+ schema: &mut Schema,
+ generator: &mut SchemaGenerator,
+) {
for (key, value) in schema.as_object_mut().into_iter().flatten() {
// This is intentionally written to work with multiple JSON Schema versions, so that
// users can add their own transforms on the end of e.g. `SchemaSettings::draft07()` and
@@ -157,14 +167,14 @@ pub fn transform_subschemas(t: &mut T, schema: &mut Schem
| "propertyNames"
| "additionalItems" => {
if let Ok(subschema) = value.try_into() {
- t.transform(subschema);
+ t.transform(subschema, generator);
}
}
"allOf" | "anyOf" | "oneOf" | "prefixItems" => {
if let Some(array) = value.as_array_mut() {
for value in array {
if let Ok(subschema) = value.try_into() {
- t.transform(subschema);
+ t.transform(subschema, generator);
}
}
}
@@ -175,18 +185,18 @@ pub fn transform_subschemas(t: &mut T, schema: &mut Schem
if let Some(array) = value.as_array_mut() {
for value in array {
if let Ok(subschema) = value.try_into() {
- t.transform(subschema);
+ t.transform(subschema, generator);
}
}
} else if let Ok(subschema) = value.try_into() {
- t.transform(subschema);
+ t.transform(subschema, generator);
}
}
"properties" | "patternProperties" | "$defs" | "definitions" => {
if let Some(obj) = value.as_object_mut() {
for value in obj.values_mut() {
if let Ok(subschema) = value.try_into() {
- t.transform(subschema);
+ t.transform(subschema, generator);
}
}
}
@@ -201,19 +211,20 @@ pub fn transform_subschemas(t: &mut T, schema: &mut Schem
pub(crate) fn transform_immediate_subschemas(
t: &mut T,
schema: &mut Schema,
+ generator: &mut SchemaGenerator,
) {
for (key, value) in schema.as_object_mut().into_iter().flatten() {
match key.as_str() {
"if" | "then" | "else" => {
if let Ok(subschema) = value.try_into() {
- t.transform(subschema);
+ t.transform(subschema, generator);
}
}
"allOf" | "anyOf" | "oneOf" => {
if let Some(array) = value.as_array_mut() {
for value in array {
if let Ok(subschema) = value.try_into() {
- t.transform(subschema);
+ t.transform(subschema, generator);
}
}
}
@@ -231,19 +242,21 @@ pub(crate) fn transform_immediate_subschemas(
///
/// # Example
/// ```
-/// # use schemars::{Schema, json_schema};
+/// # use schemars::{Schema, json_schema, SchemaGenerator};
/// use schemars::transform::{Transform, RecursiveTransform};
///
-/// let mut transform = RecursiveTransform(|schema: &mut Schema| {
+/// let mut transform = RecursiveTransform(|schema: &mut Schema, _: &mut SchemaGenerator| {
/// schema.insert("my_property".to_string(), "hello world".into());
/// });
///
+/// let mut generator = SchemaGenerator::default();
+///
/// let mut schema = json_schema!({
/// "type": "array",
/// "items": {}
/// });
///
-/// transform.transform(&mut schema);
+/// transform.transform(&mut schema, &mut generator);
///
/// assert_eq!(
/// schema,
@@ -263,9 +276,9 @@ impl Transform for RecursiveTransform
where
T: Transform,
{
- fn transform(&mut self, schema: &mut Schema) {
- self.0.transform(schema);
- transform_subschemas(self, schema);
+ fn transform(&mut self, schema: &mut Schema, generator: &mut SchemaGenerator) {
+ self.0.transform(schema, generator);
+ transform_subschemas(self, schema, generator);
}
}
@@ -282,11 +295,11 @@ pub struct ReplaceBoolSchemas {
}
impl Transform for ReplaceBoolSchemas {
- fn transform(&mut self, schema: &mut Schema) {
+ fn transform(&mut self, schema: &mut Schema, generator: &mut SchemaGenerator) {
if let Some(obj) = schema.as_object_mut() {
if self.skip_additional_properties {
if let Some((ap_key, ap_value)) = obj.remove_entry("additionalProperties") {
- transform_subschemas(self, schema);
+ transform_subschemas(self, schema, generator);
schema.insert(ap_key, ap_value);
@@ -294,7 +307,7 @@ impl Transform for ReplaceBoolSchemas {
}
}
- transform_subschemas(self, schema);
+ transform_subschemas(self, schema, generator);
} else {
schema.ensure_object();
}
@@ -310,8 +323,8 @@ impl Transform for ReplaceBoolSchemas {
pub struct RemoveRefSiblings;
impl Transform for RemoveRefSiblings {
- fn transform(&mut self, schema: &mut Schema) {
- transform_subschemas(self, schema);
+ fn transform(&mut self, schema: &mut Schema, generator: &mut SchemaGenerator) {
+ transform_subschemas(self, schema, generator);
if let Some(obj) = schema.as_object_mut().filter(|o| o.len() > 1) {
if let Some(ref_value) = obj.remove("$ref") {
@@ -335,8 +348,8 @@ impl Transform for RemoveRefSiblings {
pub struct SetSingleExample;
impl Transform for SetSingleExample {
- fn transform(&mut self, schema: &mut Schema) {
- transform_subschemas(self, schema);
+ fn transform(&mut self, schema: &mut Schema, generator: &mut SchemaGenerator) {
+ transform_subschemas(self, schema, generator);
if let Some(Value::Array(examples)) = schema.remove("examples") {
if let Some(first_example) = examples.into_iter().next() {
@@ -355,8 +368,8 @@ impl Transform for SetSingleExample {
pub struct ReplaceConstValue;
impl Transform for ReplaceConstValue {
- fn transform(&mut self, schema: &mut Schema) {
- transform_subschemas(self, schema);
+ fn transform(&mut self, schema: &mut Schema, generator: &mut SchemaGenerator) {
+ transform_subschemas(self, schema, generator);
if let Some(value) = schema.remove("const") {
schema.insert("enum".into(), Value::Array(vec![value]));
@@ -376,8 +389,8 @@ impl Transform for ReplaceConstValue {
pub struct ReplacePrefixItems;
impl Transform for ReplacePrefixItems {
- fn transform(&mut self, schema: &mut Schema) {
- transform_subschemas(self, schema);
+ fn transform(&mut self, schema: &mut Schema, generator: &mut SchemaGenerator) {
+ transform_subschemas(self, schema, generator);
if let Some(prefix_items) = schema.remove("prefixItems") {
let previous_items = schema.insert("items".to_owned(), prefix_items);
@@ -399,8 +412,8 @@ impl Transform for ReplacePrefixItems {
pub struct ReplaceUnevaluatedProperties;
impl Transform for ReplaceUnevaluatedProperties {
- fn transform(&mut self, schema: &mut Schema) {
- transform_subschemas(self, schema);
+ fn transform(&mut self, schema: &mut Schema, generator: &mut SchemaGenerator) {
+ transform_subschemas(self, schema, generator);
let Some(up) = schema.remove("unevaluatedProperties") else {
return;
@@ -409,7 +422,7 @@ impl Transform for ReplaceUnevaluatedProperties {
schema.insert("additionalProperties".to_owned(), up);
let mut gather_property_names = GatherPropertyNames::default();
- gather_property_names.transform(schema);
+ gather_property_names.transform(schema, generator);
let property_names = gather_property_names.0;
if property_names.is_empty() {
@@ -434,7 +447,7 @@ impl Transform for ReplaceUnevaluatedProperties {
struct GatherPropertyNames(BTreeSet);
impl Transform for GatherPropertyNames {
- fn transform(&mut self, schema: &mut Schema) {
+ fn transform(&mut self, schema: &mut Schema, generator: &mut SchemaGenerator) {
self.0.extend(
schema
.as_object()
@@ -445,6 +458,6 @@ impl Transform for GatherPropertyNames {
.cloned(),
);
- transform_immediate_subschemas(self, schema);
+ transform_immediate_subschemas(self, schema, generator);
}
}
diff --git a/schemars/tests/integration/deprecated.rs b/schemars/tests/integration/deprecated.rs
index 9bdfbef8..0a38a4b5 100644
--- a/schemars/tests/integration/deprecated.rs
+++ b/schemars/tests/integration/deprecated.rs
@@ -16,7 +16,7 @@ fn deprecated_struct() {
test!(DeprecatedStruct)
.assert_snapshot()
.assert_allows_ser_roundtrip_default()
- .custom(|schema, _| {
+ .custom(|schema, _, _| {
assert_eq!(
schema.as_value().pointer("/deprecated"),
Some(&Value::Bool(true)),
@@ -48,7 +48,7 @@ fn deprecated_enum() {
test!(DeprecatedEnum)
.assert_snapshot()
.assert_allows_ser_roundtrip_default()
- .custom(|schema, _| {
+ .custom(|schema, _, _| {
assert_eq!(
schema.as_value().pointer("/deprecated"),
Some(&Value::Bool(true)),
diff --git a/schemars/tests/integration/enums.rs b/schemars/tests/integration/enums.rs
index f6cd6bcf..3d8a81cc 100644
--- a/schemars/tests/integration/enums.rs
+++ b/schemars/tests/integration/enums.rs
@@ -339,7 +339,7 @@ fn unit_variants_with_doc_comments() {
.assert_snapshot()
.assert_allows_ser_roundtrip([SoundOfMusic::Do, SoundOfMusic::Re, SoundOfMusic::Mi])
.assert_rejects_de(arbitrary_values())
- .custom(|schema, _| {
+ .custom(|schema, _, _| {
assert_eq!(
schema.as_value().pointer("/oneOf/0/title"),
Some(&("A deer".into())),
diff --git a/schemars/tests/integration/extend.rs b/schemars/tests/integration/extend.rs
index e6f95068..97175dd4 100644
--- a/schemars/tests/integration/extend.rs
+++ b/schemars/tests/integration/extend.rs
@@ -17,7 +17,7 @@ struct Struct {
#[test]
fn extend_struct() {
- test!(Struct).assert_snapshot().custom(|schema, _| {
+ test!(Struct).assert_snapshot().custom(|schema, _, _| {
assert_eq!(schema.get("obj"), Some(&json!({ "array": [null, null] })));
assert_eq!(schema.get("3"), Some(&json!(3.0)));
assert_eq!(schema.get("pi"), Some(&json!(3.14)));
@@ -43,7 +43,7 @@ struct TupleStruct(
#[test]
fn extend_tuple_struct() {
- test!(TupleStruct).assert_snapshot().custom(|schema, _| {
+ test!(TupleStruct).assert_snapshot().custom(|schema, _, _| {
assert_eq!(schema.get("obj"), Some(&json!({ "array": [null, null] })));
assert_eq!(schema.get("3"), Some(&json!(3.0)));
assert_eq!(schema.get("pi"), Some(&json!(3.14)));
@@ -74,16 +74,18 @@ enum ExternalEnum {
#[test]
fn extend_externally_tagged_enum() {
- test!(ExternalEnum).assert_snapshot().custom(|schema, _| {
- assert_eq!(schema.get("foo"), Some(&json!("bar")));
-
- for i in 0..4 {
- assert_eq!(
- schema.as_value().pointer(&format!("/oneOf/{i}/foo")),
- Some(&json!("bar"))
- );
- }
- });
+ test!(ExternalEnum)
+ .assert_snapshot()
+ .custom(|schema, _, _| {
+ assert_eq!(schema.get("foo"), Some(&json!("bar")));
+
+ for i in 0..4 {
+ assert_eq!(
+ schema.as_value().pointer(&format!("/oneOf/{i}/foo")),
+ Some(&json!("bar"))
+ );
+ }
+ });
}
#[allow(dead_code)]
@@ -100,16 +102,18 @@ enum InternalEnum {
#[test]
fn extend_internally_tagged_enum() {
- test!(InternalEnum).assert_snapshot().custom(|schema, _| {
- assert_eq!(schema.get("foo"), Some(&json!("bar")));
-
- for i in 0..3 {
- assert_eq!(
- schema.as_value().pointer(&format!("/oneOf/{i}/foo")),
- Some(&json!("bar"))
- );
- }
- });
+ test!(InternalEnum)
+ .assert_snapshot()
+ .custom(|schema, _, _| {
+ assert_eq!(schema.get("foo"), Some(&json!("bar")));
+
+ for i in 0..3 {
+ assert_eq!(
+ schema.as_value().pointer(&format!("/oneOf/{i}/foo")),
+ Some(&json!("bar"))
+ );
+ }
+ });
}
#[allow(dead_code)]
@@ -128,16 +132,18 @@ enum AdjacentEnum {
#[test]
fn extend_adjacently_tagged_enum() {
- test!(AdjacentEnum).assert_snapshot().custom(|schema, _| {
- assert_eq!(schema.get("foo"), Some(&json!("bar")));
-
- for i in 0..4 {
- assert_eq!(
- schema.as_value().pointer(&format!("/oneOf/{i}/foo")),
- Some(&json!("bar"))
- );
- }
- });
+ test!(AdjacentEnum)
+ .assert_snapshot()
+ .custom(|schema, _, _| {
+ assert_eq!(schema.get("foo"), Some(&json!("bar")));
+
+ for i in 0..4 {
+ assert_eq!(
+ schema.as_value().pointer(&format!("/oneOf/{i}/foo")),
+ Some(&json!("bar"))
+ );
+ }
+ });
}
#[allow(dead_code)]
@@ -156,14 +162,16 @@ enum UntaggedEnum {
#[test]
fn extend_untagged_enum() {
- test!(UntaggedEnum).assert_snapshot().custom(|schema, _| {
- assert_eq!(schema.get("foo"), Some(&json!("bar")));
-
- for i in 0..4 {
- assert_eq!(
- schema.as_value().pointer(&format!("/anyOf/{i}/foo")),
- Some(&json!("bar"))
- );
- }
- });
+ test!(UntaggedEnum)
+ .assert_snapshot()
+ .custom(|schema, _, _| {
+ assert_eq!(schema.get("foo"), Some(&json!("bar")));
+
+ for i in 0..4 {
+ assert_eq!(
+ schema.as_value().pointer(&format!("/anyOf/{i}/foo")),
+ Some(&json!("bar"))
+ );
+ }
+ });
}
diff --git a/schemars/tests/integration/schema_name.rs b/schemars/tests/integration/schema_name.rs
index e04a7477..633027a3 100644
--- a/schemars/tests/integration/schema_name.rs
+++ b/schemars/tests/integration/schema_name.rs
@@ -14,10 +14,10 @@ struct RenamedSimpleStruct {
#[test]
fn simple() {
test!(SimpleStruct)
- .custom(|schema, _| assert_eq!(schema.get("title"), Some(&"SimpleStruct".into())));
+ .custom(|schema, _, _| assert_eq!(schema.get("title"), Some(&"SimpleStruct".into())));
test!(RenamedSimpleStruct)
- .custom(|schema, _| assert_eq!(schema.get("title"), Some(&"new-name".into())));
+ .custom(|schema, _, _| assert_eq!(schema.get("title"), Some(&"new-name".into())));
}
#[derive(JsonSchema, Deserialize, Serialize, Default)]
@@ -39,14 +39,14 @@ struct RenamedTypeParams {
#[test]
fn type_params() {
- test!(TypeParams).custom(|schema, _| {
+ test!(TypeParams).custom(|schema, _, _| {
assert_eq!(
schema.get("title"),
Some(&"TypeParams_for_uint8_and_string_and_boolean_and_null".into())
)
});
- test!(RenamedTypeParams).custom(|schema, _| {
+ test!(RenamedTypeParams).custom(|schema, _, _| {
assert_eq!(
schema.get("title"),
Some(&"new-name-null-uint8-uint8".into())
@@ -69,7 +69,7 @@ struct RenamedConstGeneric {
#[test]
fn const_generics() {
- test!(ConstGeneric<123, 'X'>).custom(|schema, _| {
+ test!(ConstGeneric<123, 'X'>).custom(|schema, _, _| {
assert_eq!(
schema.get("title"),
Some(&"ConstGeneric_for_123_and_X".into())
@@ -77,5 +77,5 @@ fn const_generics() {
});
test!(RenamedConstGeneric<123, 'X'>)
- .custom(|schema, _| assert_eq!(schema.get("title"), Some(&"new-name-123".into())));
+ .custom(|schema, _, _| assert_eq!(schema.get("title"), Some(&"new-name-123".into())));
}
diff --git a/schemars/tests/integration/settings.rs b/schemars/tests/integration/settings.rs
index f6debe6f..033d6a1e 100644
--- a/schemars/tests/integration/settings.rs
+++ b/schemars/tests/integration/settings.rs
@@ -1,5 +1,5 @@
use crate::prelude::*;
-use schemars::{generate::SchemaSettings, Schema};
+use schemars::{generate::SchemaSettings, Schema, SchemaGenerator};
#[derive(JsonSchema, Deserialize, Serialize, Default)]
pub struct OuterStruct {
@@ -53,16 +53,18 @@ fn openapi3() {
// First, move them to $defs, then run the transforms, then move them back again.
settings.transforms.insert(
0,
- Box::new(|s: &mut Schema| {
+ Box::new(|s: &mut Schema, _: &mut SchemaGenerator| {
let obj = s.ensure_object();
let defs = obj["components"]["schemas"].take();
obj.insert("$defs".to_owned(), defs);
}),
);
- settings.transforms.push(Box::new(|s: &mut Schema| {
- let obj = s.ensure_object();
- obj["components"]["schemas"] = obj.remove("$defs").unwrap();
- }));
+ settings
+ .transforms
+ .push(Box::new(|s: &mut Schema, _: &mut SchemaGenerator| {
+ let obj = s.ensure_object();
+ obj["components"]["schemas"] = obj.remove("$defs").unwrap();
+ }));
test!(OuterStruct, settings).assert_snapshot();
}
diff --git a/schemars/tests/integration/test_helper.rs b/schemars/tests/integration/test_helper.rs
index 41f937b8..ebcf70d4 100644
--- a/schemars/tests/integration/test_helper.rs
+++ b/schemars/tests/integration/test_helper.rs
@@ -1,7 +1,7 @@
use jsonschema::Validator;
use schemars::{
generate::{Contract, SchemaSettings},
- JsonSchema, Schema,
+ JsonSchema, Schema, SchemaGenerator,
};
use serde::{de::DeserializeOwned, Serialize};
use serde_json::{json, Value};
@@ -131,9 +131,10 @@ impl TestHelper {
self
}
- pub fn custom(&self, assertion: impl Fn(&Schema, Contract)) {
- assertion(&self.de_schema, Contract::Deserialize);
- assertion(&self.ser_schema, Contract::Serialize);
+ pub fn custom(&self, assertion: impl Fn(&Schema, &SchemaGenerator, Contract)) {
+ let generator = SchemaGenerator::default();
+ assertion(&self.de_schema, &generator, Contract::Deserialize);
+ assertion(&self.ser_schema, &generator, Contract::Serialize);
}
fn de_schema_validate(&self, instance: &Value) -> bool {
diff --git a/schemars/tests/integration/transform.rs b/schemars/tests/integration/transform.rs
index 94e728a8..90f56793 100644
--- a/schemars/tests/integration/transform.rs
+++ b/schemars/tests/integration/transform.rs
@@ -1,17 +1,17 @@
use crate::prelude::*;
use schemars::{
transform::{RecursiveTransform, Transform},
- Schema,
+ Schema, SchemaGenerator,
};
use serde_json::Map;
-fn insert_upper_type(schema: &mut Schema) {
+fn insert_upper_type(schema: &mut Schema, _generator: &mut SchemaGenerator) {
if let Some(Value::String(ty)) = schema.get("type") {
schema.insert("x-upperType".to_owned(), ty.to_uppercase().into());
}
}
-fn insert_property_count(schema: &mut Schema) {
+fn insert_property_count(schema: &mut Schema, _: &mut SchemaGenerator) {
let count = schema
.get("properties")
.and_then(Value::as_object)
@@ -53,16 +53,21 @@ fn transform_enum() {
.custom(assert_upper_type_valid);
}
-fn assert_upper_type_valid(schema: &Schema, _: schemars::generate::Contract) {
+fn assert_upper_type_valid(
+ schema: &Schema,
+ generator: &SchemaGenerator,
+ _: schemars::generate::Contract,
+) {
let mut schema = schema.clone();
+ let mut generator = generator.clone();
- RecursiveTransform(|s: &mut Schema| {
+ RecursiveTransform(|s: &mut Schema, _: &mut SchemaGenerator| {
assert_eq!(
s.remove("x-upperType").map(|v| v.to_string()),
s.get("type").map(|v| v.to_string().to_uppercase()),
);
})
- .transform(&mut schema);
+ .transform(&mut schema, &mut generator);
assert!(!schema.to_value().to_string().contains("x-upperType"));
}
diff --git a/schemars/tests/ui/transform_str.stderr b/schemars/tests/ui/transform_str.stderr
index 50cf7b94..d1f037a8 100644
--- a/schemars/tests/ui/transform_str.stderr
+++ b/schemars/tests/ui/transform_str.stderr
@@ -1,4 +1,4 @@
-error: Expected a `fn(&mut Schema)` or other value implementing `schemars::transform::Transform`, found `&str`.
+error: Expected a `fn(&mut Schema, &mut SchemaGenerator)` or other value implementing `schemars::transform::Transform`, found `&str`.
Did you mean `#[schemars(transform = x)]`?
--> tests/ui/transform_str.rs:4:24
|
diff --git a/schemars_derive/src/attr/mod.rs b/schemars_derive/src/attr/mod.rs
index 37350d33..b03d4188 100644
--- a/schemars_derive/src/attr/mod.rs
+++ b/schemars_derive/src/attr/mod.rs
@@ -11,7 +11,7 @@ use syn::Ident;
use syn::{punctuated::Punctuated, Attribute, Expr, ExprLit, Lit, Meta, Path, Type};
use validation::ValidationAttrs;
-use crate::idents::SCHEMA;
+use crate::idents::{GENERATOR, SCHEMA};
pub use schemars_to_serde::process_serde_attrs;
@@ -131,7 +131,7 @@ impl CommonAttrs {
cx.error_spanned_by(
&expr,
format_args!(
- "Expected a `fn(&mut Schema)` or other value implementing `schemars::transform::Transform`, found `&str`.\nDid you mean `#[schemars(transform = {})]`?",
+ "Expected a `fn(&mut Schema, &mut SchemaGenerator)` or other value implementing `schemars::transform::Transform`, found `&str`.\nDid you mean `#[schemars(transform = {})]`?",
lit_str.value()
),
)
@@ -211,7 +211,7 @@ impl CommonAttrs {
for transform in &self.transforms {
mutators.push(quote! {
- schemars::transform::Transform::transform(&mut #transform, &mut #SCHEMA);
+ schemars::transform::Transform::transform(&mut #transform, &mut #SCHEMA, #GENERATOR);
});
}
}