Repository: jonasbb/serde_with
Pull request #760 (2024-06-28 20:59:35)

Implement JsonSchemaAs for OneOrMany instead of JsonSchema
Currently, there is an `impl JsonSchema for WrapSchema<OneOrMany<...>>`. This works fine if you only directly need `OneOrMany` but causes errors if you want to nest it (e.g. `Option<OneOrMany<_>>`).

This PR changes the impl to a `JsonSchemaAs` impl, which is the correct approach. I think I just missed these ones during a rebase. In any case, the change should be fully backwards compatible due to the blanket schema impl.

I have added a snapshot test. The actual snapshot doesn't matter - the real test is that the struct below compiles

```rust
#[serde_as]
#[derive(Serialize, Deserialize, JsonSchema)]
struct Test {
    #[serde_as(as = "Option<OneOrMany<_>>")]
    optional_vec: Option<Vec<String>>,
}
```


Patch:
diff --git a/serde_with/src/schemars_0_8.rs b/serde_with/src/schemars_0_8.rs
index 1696bd8..e7e1fcb 100644
--- a/serde_with/src/schemars_0_8.rs
+++ b/serde_with/src/schemars_0_8.rs
@@ -794,9 +794,9 @@ map_first_last_wins_schema!(=> S indexmap_1::IndexMap<K, V, S>);
 #[cfg(feature = "indexmap_2")]
 map_first_last_wins_schema!(=> S indexmap_2::IndexMap<K, V, S>);
 
-impl<T, TA> JsonSchema for WrapSchema<Vec<T>, OneOrMany<TA, PreferOne>>
+impl<T, TA> JsonSchemaAs<Vec<T>> for OneOrMany<TA, PreferOne>
 where
-    WrapSchema<T, TA>: JsonSchema,
+    TA: JsonSchemaAs<T>,
 {
     fn schema_name() -> String {
         std::format!(
@@ -835,9 +835,9 @@ where
     }
 }
 
-impl<T, TA> JsonSchema for WrapSchema<Vec<T>, OneOrMany<TA, PreferMany>>
+impl<T, TA> JsonSchemaAs<Vec<T>> for OneOrMany<TA, PreferMany>
 where
-    WrapSchema<T, TA>: JsonSchema,
+    TA: JsonSchemaAs<T>,
 {
     fn schema_name() -> String {
         std::format!(


Test patch:
diff --git a/serde_with/tests/schemars_0_8.rs b/serde_with/tests/schemars_0_8.rs
index 2c909c6..4237aa4 100644
--- a/serde_with/tests/schemars_0_8.rs
+++ b/serde_with/tests/schemars_0_8.rs
@@ -406,6 +406,13 @@ mod snapshots {
                 value: u32
             }
         }
+
+        one_or_many_nested {
+            struct Test {
+                #[serde_as(as = "Option<OneOrMany<_>>")]
+                optional_many: Option<Vec<String>>,
+            }
+        }
     }
 }
 
diff --git a/serde_with/tests/schemars_0_8/snapshots/one_or_many_nested.json b/serde_with/tests/schemars_0_8/snapshots/one_or_many_nested.json
new file mode 100644
index 0000000..67c4ce9
--- /dev/null
+++ b/serde_with/tests/schemars_0_8/snapshots/one_or_many_nested.json
@@ -0,0 +1,33 @@
+{
+  "$schema": "http://json-schema.org/draft-07/schema#",
+  "title": "Test",
+  "type": "object",
+  "properties": {
+    "optional_many": {
+      "default": null,
+      "anyOf": [
+        {
+          "$ref": "#/definitions/OneOrMany<String, PreferOne>"
+        },
+        {
+          "type": "null"
+        }
+      ]
+    }
+  },
+  "definitions": {
+    "OneOrMany<String, PreferOne>": {
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "type": "array",
+          "items": {
+            "type": "string"
+          }
+        }
+      ]
+    }
+  }
+}