Repository: GREsau/schemars
Pull request #67 (2020-12-27 13:45:36)

Fix #[schemars(with = ...)] alongside #[serde(transparent)]
`#typedef` is not allowed in that position:
```
error: struct is not supported in `trait`s or `impl`s
```

(diff is easier to read ignoring whitespace: append `?w=1` to the url).

I'd love a patch release including this fix, if that's possible.

(My motivation is that I want a string field that has a `pattern`, so I'm doing something like:
```
#[serde(transparent)]
pub struct StringWithMyPattern(#[schemars(schema_with = "string_with_my_pattern")] pub String);
```

I see that #12 considers cleaner approaches - something like `#[schemars(pattern = "regex")]` would be good for me.  I considered trying to make progress on implementing that, but to be honest I wasn't sure how to get started)

dimbleby: Ugh, underscore_const_names was stabilized in 1.37.0.

Do I need to find another way to write this, or can I just bump the minimum supported version?
dimbleby: I see that #68 is failing CI at 1.36 for the same reason

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 816e514..cf633b8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -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.
@@ -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).
\ No newline at end of file
+    - 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).
diff --git a/schemars_derive/src/lib.rs b/schemars_derive/src/lib.rs
index d50a890..3746771 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<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)
+                    }
+                };
             };
         };
     }


Test patch:
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 0000000..9f6afb3
--- /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 1e94149..db85d80 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::<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")
+}