diff --git a/utoipa-gen/src/component/schema.rs b/utoipa-gen/src/component/schema.rs index 9b76487f..12696af1 100644 --- a/utoipa-gen/src/component/schema.rs +++ b/utoipa-gen/src/component/schema.rs @@ -619,6 +619,14 @@ impl ToTokensDiagnostics for UnnamedStructSchema<'_> { if fields_len == 1 { if let Some(ref mut features) = unnamed_struct_features { + let inline = + features::parse_schema_features_with(&first_field.attrs, |input| { + Ok(parse_features!(input as super::features::Inline)) + })? + .unwrap_or_default(); + + features.extend(inline); + if pop_feature!(features => Feature::Default(crate::features::Default(None))) .is_some() { diff --git a/utoipa-gen/src/lib.rs b/utoipa-gen/src/lib.rs index dfe9078c..04d63245 100644 --- a/utoipa-gen/src/lib.rs +++ b/utoipa-gen/src/lib.rs @@ -133,6 +133,30 @@ use self::{ /// _`rename`_ attribute. It behaves similarly to serde's _`rename`_ attribute. If both _serde_ /// _`rename`_ and _schema_ _`rename`_ are defined __serde__ will take precedence. /// +/// ## Enum Unnamed Variant Field Configuration Options +/// +/// * `inline` If the type of this field implements [`ToSchema`][to_schema], then the schema definition +/// will be inlined. **warning:** Don't use this for recursive data types! +/// +/// _**Inline unnamed field variant schemas.**_ +/// ```rust +/// # use utoipa::ToSchema; +/// # #[derive(ToSchema)] +/// # enum Number { +/// # One, +/// # } +/// # +/// # #[derive(ToSchema)] +/// # enum Color { +/// # Spade, +/// # } +/// #[derive(ToSchema)] +/// enum Card { +/// Number(#[schema(inline)] Number), +/// Color(#[schema(inline)] Color), +/// } +/// ``` +/// /// # Unnamed Field Struct Optional Configuration Options for `#[schema(...)]` /// * `description = ...` Can be literal string or Rust expression e.g. _`const`_ reference or /// `include_str!(...)` statement. This can be used to override **default** description what is diff --git a/utoipa-gen/tests/schema_derive_test.rs b/utoipa-gen/tests/schema_derive_test.rs index 57a05434..91463742 100644 --- a/utoipa-gen/tests/schema_derive_test.rs +++ b/utoipa-gen/tests/schema_derive_test.rs @@ -2788,6 +2788,86 @@ fn derive_struct_with_nullable_and_required() { ) } +#[test] +fn derive_enum_with_inline_variant() { + #[allow(dead_code)] + #[derive(ToSchema)] + enum Number { + One, + Two, + Three, + Four, + Five, + Six, + Seven, + Height, + Nine, + } + + #[allow(dead_code)] + #[derive(ToSchema)] + enum Color { + Spade, + Heart, + Club, + Diamond, + } + + let card = api_doc! { + enum Card { + Number(#[schema(inline)] Number), + Color(#[schema(inline)] Color), + } + }; + + assert_json_eq!( + card, + json!({ + "oneOf": [ + { + "properties": { + "Number": { + "enum": [ + "One", + "Two", + "Three", + "Four", + "Five", + "Six", + "Seven", + "Height", + "Nine", + ], + "type": "string", + }, + }, + "required": [ + "Number", + ], + "type": "object", + }, + { + "properties": { + "Color": { + "enum": [ + "Spade", + "Heart", + "Club", + "Diamond", + ], + "type": "string", + }, + }, + "required": [ + "Color", + ], + "type": "object", + }, + ], + }) + ); +} + #[test] fn derive_struct_xml() { let user = api_doc! {