From 883d765f0a0d5ca3451175f8630f963e515c2c98 Mon Sep 17 00:00:00 2001 From: TLDMain <119927819+TLDMain@users.noreply.github.com> Date: Fri, 15 Nov 2024 22:20:21 +0300 Subject: [PATCH 1/3] fix: tagged enum with flatten fields --- utoipa-gen/src/component/schema.rs | 11 +++++- utoipa-gen/src/component/schema/enums.rs | 22 ++++++++--- utoipa-gen/tests/schema_derive_test.rs | 49 ++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 6 deletions(-) diff --git a/utoipa-gen/src/component/schema.rs b/utoipa-gen/src/component/schema.rs index 66a84a3a..1381d9cd 100644 --- a/utoipa-gen/src/component/schema.rs +++ b/utoipa-gen/src/component/schema.rs @@ -313,6 +313,7 @@ pub struct NamedStructSchema { pub schema_as: Option, fields_references: Vec, bound: Option, + is_all_of: bool, } #[cfg_attr(feature = "debug", derive(Debug))] @@ -385,6 +386,7 @@ impl NamedStructSchema { .flatten() .collect::>(); + let mut object_tokens_empty = true; let object_tokens = fields_vec .iter() .filter(|(_, field_rules, ..)| !field_rules.skip && !field_rules.flatten) @@ -415,6 +417,7 @@ impl NamedStructSchema { _field, field_schema, )| { + object_tokens_empty = false; let rename_to = field_rules .rename .as_deref() @@ -513,8 +516,13 @@ impl NamedStructSchema { tokens.extend(quote! { utoipa::openapi::AllOfBuilder::new() #flattened_tokens - .item(#object_tokens) + }); + if !object_tokens_empty { + tokens.extend(quote! { + .item(#object_tokens) + }); + } true } } else { @@ -552,6 +560,7 @@ impl NamedStructSchema { schema_as, fields_references, bound, + is_all_of: all_of, }) } diff --git a/utoipa-gen/src/component/schema/enums.rs b/utoipa-gen/src/component/schema/enums.rs index b2c9f925..a9e8971a 100644 --- a/utoipa-gen/src/component/schema/enums.rs +++ b/utoipa-gen/src/component/schema/enums.rs @@ -517,12 +517,24 @@ impl MixedEnumContent { MixedEnumContent::split_enum_features(variant_features); let schema = NamedStructSchema::new(root, fields, variant_features)?; - let schema_tokens = schema.to_token_stream(); + let mut schema_tokens = schema.to_token_stream(); ( - EnumSchema::::tagged(schema_tokens) - .tag(tag, PlainSchema::for_name(name.as_ref())) - .features(enum_features) - .to_token_stream(), + if schema.is_all_of { + let object_builder_tokens = quote! { utoipa::openapi::schema::Object::builder() }; + let enum_schema_tokens = EnumSchema::::tagged(object_builder_tokens) + .tag(tag, PlainSchema::for_name(name.as_ref())) + .features(enum_features) + .to_token_stream(); + schema_tokens.extend(quote! { + .item(#enum_schema_tokens) + }); + schema_tokens + } else { + EnumSchema::::tagged(schema_tokens) + .tag(tag, PlainSchema::for_name(name.as_ref())) + .features(enum_features) + .to_token_stream() + }, schema.fields_references, ) } diff --git a/utoipa-gen/tests/schema_derive_test.rs b/utoipa-gen/tests/schema_derive_test.rs index ce264118..68e2f020 100644 --- a/utoipa-gen/tests/schema_derive_test.rs +++ b/utoipa-gen/tests/schema_derive_test.rs @@ -1089,6 +1089,55 @@ fn derive_simple_enum_serde_tag() { ); } +#[test] +fn derive_simple_enum_serde_tag_with_flatten_content() { + #[derive(Serialize, ToSchema)] + #[allow(unused)] + struct Foo { + name: &'static str, + } + + let value: Value = api_doc! { + #[derive(Serialize)] + #[serde(tag = "tag")] + enum Bar { + One { + #[serde(flatten)] + foo: Foo, + }, + } + }; + + assert_json_eq!( + value, + json!({ + "oneOf": [ + { + "allOf": [ + { + "$ref": "#/components/schemas/Foo", + }, + { + "type": "object", + "properties": { + "tag": { + "type": "string", + "enum": [ + "One", + ], + }, + }, + "required": [ + "tag", + ], + }, + ], + }, + ], + }) + ); +} + #[test] fn derive_simple_enum_serde_untagged() { let value: Value = api_doc! { From 34f53d67a0c60bbace4bc9236ddfd5c96d628216 Mon Sep 17 00:00:00 2001 From: TLDMain <119927819+TLDMain@users.noreply.github.com> Date: Tue, 26 Nov 2024 12:17:46 +0300 Subject: [PATCH 2/3] fix: format --- utoipa-gen/src/component/schema/enums.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/utoipa-gen/src/component/schema/enums.rs b/utoipa-gen/src/component/schema/enums.rs index a9e8971a..54602199 100644 --- a/utoipa-gen/src/component/schema/enums.rs +++ b/utoipa-gen/src/component/schema/enums.rs @@ -520,11 +520,13 @@ impl MixedEnumContent { let mut schema_tokens = schema.to_token_stream(); ( if schema.is_all_of { - let object_builder_tokens = quote! { utoipa::openapi::schema::Object::builder() }; - let enum_schema_tokens = EnumSchema::::tagged(object_builder_tokens) - .tag(tag, PlainSchema::for_name(name.as_ref())) - .features(enum_features) - .to_token_stream(); + let object_builder_tokens = + quote! { utoipa::openapi::schema::Object::builder() }; + let enum_schema_tokens = + EnumSchema::::tagged(object_builder_tokens) + .tag(tag, PlainSchema::for_name(name.as_ref())) + .features(enum_features) + .to_token_stream(); schema_tokens.extend(quote! { .item(#enum_schema_tokens) }); From c8369cd49b3e2338fd05dfbcedb3db02a1e5bc78 Mon Sep 17 00:00:00 2001 From: TLDMain <119927819+TLDMain@users.noreply.github.com> Date: Thu, 28 Nov 2024 13:11:41 +0300 Subject: [PATCH 3/3] upd: changelog entry --- utoipa-gen/CHANGELOG.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/utoipa-gen/CHANGELOG.md b/utoipa-gen/CHANGELOG.md index 8b13cb60..2da35c7e 100644 --- a/utoipa-gen/CHANGELOG.md +++ b/utoipa-gen/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog - utoipa-gen +## Unreleased + +### Fixed + +* Fix tagged enum with flatten fields (https://github.com/juhaku/utoipa/pull/1208) + ## 5.2.0 - Nov 2024 ### Fixed @@ -454,7 +460,7 @@ * Add support for multiple examples in response (https://github.com/juhaku/utoipa/pull/403) * Add Example type to OpenApi types (https://github.com/juhaku/utoipa/pull/402) * Add derive info support for derive OpenApi (https://github.com/juhaku/utoipa/pull/400) -* Add `merge` functionality for `OpenApi` (https://github.com/juhaku/utoipa/pull/397) +* Add `merge` functionality for `OpenApi` (https://github.com/juhaku/utoipa/pull/397) * Add derive servers attribute for OpenApi (https://github.com/juhaku/utoipa/pull/395) * Add support for unit sructs (https://github.com/juhaku/utoipa/pull/392) * Add support for `schema_with` custom fn reference (https://github.com/juhaku/utoipa/pull/390)