Skip to content

Commit

Permalink
Fix #[schemars(with = ...)] alongside #[serde(transparent)] (#67)
Browse files Browse the repository at this point in the history
Co-authored-by: Graham Esau <gesau@hotmail.co.uk>
  • Loading branch information
dimbleby and GREsau authored Mar 21, 2021
1 parent 1c9ecaf commit c4ef7ba
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 30 deletions.
7 changes: 4 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@

### Changed:
- Minimum supported rust version is now 1.37.0

### Changed:
- Deriving JsonSchema on enums now sets `additionalProperties` to false on generated schemas wherever serde doesn't accept unknown properties. This includes non-unit variants of externally tagged enums, and struct-style variants of all enums that have the `deny_unknown_fields` attribute.

### Fixed
- Fix use of `#[serde(transparent)]` in combination with `#[schemars(with = ...)]` (https://github.com/GREsau/schemars/pull/67)

## [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.
Expand Down Expand Up @@ -128,4 +129,4 @@
- Made prepositions/conjunctions in generated schema names lowercase
- e.g. schema name for `Result<MyStruct, Vec<String>>` 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<i8>` and `MyStruct<usize>` 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).
- Previously, schema generation would incorrectly assume types such as `MyStruct<i8>` and `MyStruct<usize>` 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).
5 changes: 5 additions & 0 deletions schemars/tests/expected/schema_with-transparent-newtype.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "schema_fn",
"type": "boolean"
}
9 changes: 9 additions & 0 deletions schemars/tests/schema_with_struct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,12 @@ pub struct Newtype(#[schemars(schema_with = "schema_fn")] DoesntImplementJsonSch
fn struct_newtype() -> TestResult {
test_default_generated_schema::<Newtype>("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::<TransparentNewtype>("schema_with-transparent-newtype")
}
56 changes: 29 additions & 27 deletions schemars_derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<schemars::schema::Metadata>,
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<schemars::schema::Metadata>,
required: bool,
) {
<#ty as schemars::JsonSchema>::add_schema_as_property(gen, parent, name, metadata, required)
}
};
};
};
}
Expand Down

0 comments on commit c4ef7ba

Please sign in to comment.