From 567f3a369f014421cc8057bc17c29338ba35ea3e Mon Sep 17 00:00:00 2001 From: David Hotham Date: Sun, 27 Dec 2020 13:37:33 +0000 Subject: [PATCH 1/2] Fix #[schemars(with = ...)] alongside #[serde(transparent)] --- CHANGELOG.md | 6 +++- schemars_derive/src/lib.rs | 56 ++++++++++++++++++++------------------ 2 files changed, 34 insertions(+), 28 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a0cd6c6..9a46ee1c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## Unreleased +### Fixed +- Fix use of `#[serde(transparent)]` in combination with `#[schemars(with = ...)]`. + ## [0.8.0] - 2020-09-27 ### Added: - `visit::Visitor`, a trait for updating a schema and all schemas it contains recursively. A `SchemaSettings` can now contain a list of visitors. @@ -118,4 +122,4 @@ - Made prepositions/conjunctions in generated schema names lowercase - e.g. schema name for `Result>` has changed from "Result_Of_MyStruct_Or_Array_Of_String" to "Result_of_MyStruct_or_Array_of_String" - Some provided `JsonSchema` implementations with the same `type` but different `format`s (e.g. `i8` and `usize`) used the `type` as their name. They have now been updated to use `format` as their name. - - Previously, schema generation would incorrectly assume types such as `MyStruct` and `MyStruct` were identical, and give them a single schema definition called `MyStruct_for_Integer` despite the fact they should have different schemas. Now they will each have their own schema (`MyStruct_for_i8` and `MyStruct_for_usize` respectively). \ No newline at end of file + - Previously, schema generation would incorrectly assume types such as `MyStruct` and `MyStruct` were identical, and give them a single schema definition called `MyStruct_for_Integer` despite the fact they should have different schemas. Now they will each have their own schema (`MyStruct_for_i8` and `MyStruct_for_usize` respectively). diff --git a/schemars_derive/src/lib.rs b/schemars_derive/src/lib.rs index d50a8903..37467716 100644 --- a/schemars_derive/src/lib.rs +++ b/schemars_derive/src/lib.rs @@ -38,35 +38,37 @@ fn derive_json_schema(mut input: syn::DeriveInput) -> TokenStream { if let Some(transparent_field) = cont.transparent_field() { let (ty, type_def) = schema_exprs::type_for_schema(transparent_field, 0); return quote! { - #[automatically_derived] - impl #impl_generics schemars::JsonSchema for #type_name #ty_generics #where_clause { + const _: () = { #type_def - fn is_referenceable() -> bool { - <#ty as schemars::JsonSchema>::is_referenceable() - } - - fn schema_name() -> std::string::String { - <#ty as schemars::JsonSchema>::schema_name() - } - - fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - <#ty as schemars::JsonSchema>::json_schema(gen) - } - - fn json_schema_for_flatten(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { - <#ty as schemars::JsonSchema>::json_schema_for_flatten(gen) - } - - fn add_schema_as_property( - gen: &mut schemars::gen::SchemaGenerator, - parent: &mut schemars::schema::SchemaObject, - name: String, - metadata: Option, - required: bool, - ) { - <#ty as schemars::JsonSchema>::add_schema_as_property(gen, parent, name, metadata, required) - } + #[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 schema_name() -> std::string::String { + <#ty as schemars::JsonSchema>::schema_name() + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + <#ty as schemars::JsonSchema>::json_schema(gen) + } + + fn json_schema_for_flatten(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + <#ty as schemars::JsonSchema>::json_schema_for_flatten(gen) + } + + fn add_schema_as_property( + gen: &mut schemars::gen::SchemaGenerator, + parent: &mut schemars::schema::SchemaObject, + name: String, + metadata: Option, + required: bool, + ) { + <#ty as schemars::JsonSchema>::add_schema_as_property(gen, parent, name, metadata, required) + } + }; }; }; } From 2d314df894eec4d3e79dceb4ae73070aa696e73c Mon Sep 17 00:00:00 2001 From: Graham Esau Date: Sun, 21 Mar 2021 13:52:13 +0000 Subject: [PATCH 2/2] Add unit test --- .../tests/expected/schema_with-transparent-newtype.json | 5 +++++ schemars/tests/schema_with_struct.rs | 9 +++++++++ 2 files changed, 14 insertions(+) create mode 100644 schemars/tests/expected/schema_with-transparent-newtype.json diff --git a/schemars/tests/expected/schema_with-transparent-newtype.json b/schemars/tests/expected/schema_with-transparent-newtype.json new file mode 100644 index 00000000..9f6afb36 --- /dev/null +++ b/schemars/tests/expected/schema_with-transparent-newtype.json @@ -0,0 +1,5 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "schema_fn", + "type": "boolean" +} \ No newline at end of file diff --git a/schemars/tests/schema_with_struct.rs b/schemars/tests/schema_with_struct.rs index 1e94149e..db85d807 100644 --- a/schemars/tests/schema_with_struct.rs +++ b/schemars/tests/schema_with_struct.rs @@ -42,3 +42,12 @@ pub struct Newtype(#[schemars(schema_with = "schema_fn")] DoesntImplementJsonSch fn struct_newtype() -> TestResult { test_default_generated_schema::("schema_with-newtype") } + +#[derive(Debug, JsonSchema)] +#[schemars(transparent)] +pub struct TransparentNewtype(#[schemars(schema_with = "schema_fn")] DoesntImplementJsonSchema); + +#[test] +fn struct_transparent_newtype() -> TestResult { + test_default_generated_schema::("schema_with-transparent-newtype") +}