diff --git a/serde_with/CHANGELOG.md b/serde_with/CHANGELOG.md index af3604e3..a19d52df 100644 --- a/serde_with/CHANGELOG.md +++ b/serde_with/CHANGELOG.md @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased] +### Fixed + +* Do not emit `schemars(deserialize_with = "...")` annotations, as `schemars` does not support them (#735) + Thanks to @sivizius for reporting the issue. + ## [3.8.0] - 2024-04-24 ### Added diff --git a/serde_with/tests/schemars_0_8.rs b/serde_with/tests/schemars_0_8.rs index 03e2c4b1..2c909c65 100644 --- a/serde_with/tests/schemars_0_8.rs +++ b/serde_with/tests/schemars_0_8.rs @@ -117,6 +117,44 @@ fn schemars_custom_with() { })); } +#[test] +fn schemars_deserialize_only_bug_735() { + #[serde_as] + #[derive(JsonSchema, Serialize)] + #[schemars(crate = "::schemars_0_8")] + struct Basic { + /// Basic field, no attribute + bare_field: u32, + + /// Will emit matching schemars attribute + #[serde_as(as = "PickFirst<(_, DisplayFromStr)>")] + both: u32, + + /// Can emit schemars with serialize_as, but it will be ignored + #[serde_as(serialize_as = "PickFirst<(_, DisplayFromStr)>")] + serialize_only: u32, + + /// schemars doesn't support deserialize_as + #[serde_as(deserialize_as = "PickFirst<(_, DisplayFromStr)>")] + deserialize_only: u32, + + /// Can emit schemars with serialize_as, but it will be ignored + /// schemars doesn't support deserialize_as + #[serde_as( + serialize_as = "PickFirst<(_, DisplayFromStr)>", + deserialize_as = "PickFirst<(_, DisplayFromStr)>" + )] + serialize_and_deserialize: u32, + } + + let schema = schemars::schema_for!(Basic); + let mut schema = serde_json::to_string_pretty(&schema).expect("schema could not be serialized"); + schema.push('\n'); + + let expected = expect_file!["./schemars_0_8/schemars_deserialize_only_bug_735.json"]; + expected.assert_eq(&schema); +} + #[test] fn schemars_custom_schema_with() { fn custom_int(_: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { diff --git a/serde_with/tests/schemars_0_8/schemars_deserialize_only_bug_735.json b/serde_with/tests/schemars_0_8/schemars_deserialize_only_bug_735.json new file mode 100644 index 00000000..8ad0d16a --- /dev/null +++ b/serde_with/tests/schemars_0_8/schemars_deserialize_only_bug_735.json @@ -0,0 +1,65 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Basic", + "type": "object", + "required": [ + "bare_field", + "both", + "deserialize_only", + "serialize_and_deserialize", + "serialize_only" + ], + "properties": { + "bare_field": { + "description": "Basic field, no attribute", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "both": { + "description": "Will emit matching schemars attribute", + "allOf": [ + { + "$ref": "#/definitions/PickFirst<(uint32String)>" + } + ] + }, + "deserialize_only": { + "description": "schemars doesn't support deserialize_as", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "serialize_and_deserialize": { + "description": "Can emit schemars with serialize_as, but it will be ignored schemars doesn't support deserialize_as", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "serialize_only": { + "description": "Can emit schemars with serialize_as, but it will be ignored", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "definitions": { + "PickFirst<(uint32String)>": { + "anyOf": [ + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + { + "writeOnly": true, + "allOf": [ + { + "type": "string" + } + ] + } + ] + } + } +} diff --git a/serde_with_macros/src/lib.rs b/serde_with_macros/src/lib.rs index 196ebc65..b138a939 100644 --- a/serde_with_macros/src/lib.rs +++ b/serde_with_macros/src/lib.rs @@ -799,23 +799,6 @@ fn serde_as_add_attr_to_field( quote!(#serde_with_crate_path::As::<#replacement_type>::deserialize).to_string(); let attr = parse_quote!(#[serde(deserialize_with = #attr_inner_tokens)]); field.attrs.push(attr); - - if let Some(cfg) = schemars_config.cfg_expr() { - let with_cfg = utils::schemars_with_attr_if( - &field.attrs, - &["with", "deserialize_with", "schema_with"], - )?; - let attr_inner_tokens = - quote!(#serde_with_crate_path::Schema::<#type_original, #replacement_type>::deserialize) - .to_string(); - let attr = parse_quote! { - #[cfg_attr( - all(#cfg, not(#with_cfg)), - schemars(deserialize_with = #attr_inner_tokens)) - ] - }; - field.attrs.push(attr); - } } if let Some(type_) = serde_as_options.serialize_as { let replacement_type = replace_infer_type_with_type(type_.clone(), type_same); @@ -823,23 +806,6 @@ fn serde_as_add_attr_to_field( quote!(#serde_with_crate_path::As::<#replacement_type>::serialize).to_string(); let attr = parse_quote!(#[serde(serialize_with = #attr_inner_tokens)]); field.attrs.push(attr); - - if let Some(cfg) = schemars_config.cfg_expr() { - let with_cfg = utils::schemars_with_attr_if( - &field.attrs, - &["with", "serialize_with", "schema_with"], - )?; - let attr_inner_tokens = - quote!(#serde_with_crate_path::Schema::<#type_original, #replacement_type>::serialize) - .to_string(); - let attr = parse_quote! { - #[cfg_attr( - all(#cfg, not(#with_cfg)), - schemars(serialize_with = #attr_inner_tokens)) - ] - }; - field.attrs.push(attr); - } } Ok(())