Repository: poem-web/poem (Rust)

Issue:
Union intermediate types don't include the variant name
## Expected Behavior
I'm trying to generate a `Union` enumeration where some of the variants use the same type for their contents.  In this case, the enumeration represents a state machine where some states share the same contents.  I want the states to be separate though as they represent different points in the machine.  A minimal example looks like:

```
#[derive(Object)]
struct Details {
    pub field: i32,
}

#[derive(Union)]
#[oai(discriminator_name = "state")]
#[oai(one_of)]
enum State {
    Variant1(Details),
    Variant2(Details),
}
```

Ideally the generated OpenAPI definition would still fully distinguish between these states.

## Actual Behavior
The actual generated schema generates one type for both variants, which makes them indistinguishable and not a valid `oneOf` OpenAPI type.  The generated schema looks like:

```
components:
  schemas:
    Details:
      type: object
      title: Details
      required:
      - field
      properties:
        field:
          type: integer
          format: int32
    State:
      type: object
      oneOf:
      - $ref: '#/components/schemas/State_Details'
      - $ref: '#/components/schemas/State_Details'
      discriminator:
        propertyName: state
        mapping:
          Variant1: '#/components/schemas/State_Details'
          Variant2: '#/components/schemas/State_Details'
    State_Details:
      allOf:
      - type: object
        required:
        - state
        properties:
          state:
            type: string
            enum:
            - Variant2
            example: Variant2
      - $ref: '#/components/schemas/Details'
```


## Steps to Reproduce the Problem
I've created a full sample here: https://github.com/MJDSys/poem-repo

The issue seems to be here: https://github.com/poem-web/poem/blob/db58a4a85dc8c1bcb7ab7798b425cf10f7034b85/poem-openapi-derive/src/union.rs#L83

Where the schema name is generated based on the type of the interior struct.  If it is an acceptable change, I could submit a PR changing this to be based on the variant's name in the enumeration which would be unique.

## Specifications

- Version: 5.1.14
- Platform: Linux
- Subsystem: poem-openapi


Discussion:
Feel free to make a pr if it works for you~



Patch:
diff --git a/poem-openapi-derive/src/union.rs b/poem-openapi-derive/src/union.rs
index 50143cacb2..266f95f90e 100644
--- a/poem-openapi-derive/src/union.rs
+++ b/poem-openapi-derive/src/union.rs
@@ -90,8 +90,9 @@ pub(crate) fn generate(args: DeriveInput) -> GeneratorResult<TokenStream> {
         }
 
         let object_ty = &variant.fields.fields[0];
+        let format_string = format!("{{}}_{}", item_ident);
         let schema_name = quote! {
-            ::std::format!("{}_{}", <Self as #crate_name::types::Type>::name(), <#object_ty as #crate_name::types::Type>::name())
+            ::std::format!(#format_string, <Self as #crate_name::types::Type>::name())
         };
         let mapping_name = match &variant.mapping {
             Some(mapping) => mapping.clone(),


Test patch:
diff --git a/poem-openapi/tests/union.rs b/poem-openapi/tests/union.rs
index 7436201d6d..adeee29ec1 100644
--- a/poem-openapi/tests/union.rs
+++ b/poem-openapi/tests/union.rs
@@ -22,7 +22,7 @@ fn get_meta_by_name<T: Type>(name: &str) -> MetaSchema {
 #[test]
 fn with_discriminator() {
     #[derive(Object, Debug, PartialEq)]
-    struct A {
+    struct AContents {
         v1: i32,
         v2: String,
     }
@@ -35,7 +35,7 @@ fn with_discriminator() {
     #[derive(Union, Debug, PartialEq)]
     #[oai(discriminator_name = "type")]
     enum MyObj {
-        A(A),
+        A(AContents),
         B(B),
     }
 
@@ -79,7 +79,7 @@ fn with_discriminator() {
                     )],
                     ..MetaSchema::new("object")
                 })),
-                MetaSchemaRef::Reference("A".to_string()),
+                MetaSchemaRef::Reference("AContents".to_string()),
             ],
             ..MetaSchema::ANY
         }
@@ -116,14 +116,14 @@ fn with_discriminator() {
             "v2": "hello",
         })))
         .unwrap(),
-        MyObj::A(A {
+        MyObj::A(AContents {
             v1: 100,
             v2: "hello".to_string()
         })
     );
 
     assert_eq!(
-        MyObj::A(A {
+        MyObj::A(AContents {
             v1: 100,
             v2: "hello".to_string()
         })
@@ -559,17 +559,17 @@ fn rename_all() {
                 mapping: vec![
                     (
                         "putInt".to_string(),
-                        "#/components/schemas/MyObj_A".to_string()
+                        "#/components/schemas/MyObj_PutInt".to_string()
                     ),
                     (
                         "putString".to_string(),
-                        "#/components/schemas/MyObj_B".to_string()
+                        "#/components/schemas/MyObj_PutString".to_string()
                     ),
                 ]
             }),
             any_of: vec![
-                MetaSchemaRef::Reference("MyObj_A".to_string()),
-                MetaSchemaRef::Reference("MyObj_B".to_string()),
+                MetaSchemaRef::Reference("MyObj_PutInt".to_string()),
+                MetaSchemaRef::Reference("MyObj_PutString".to_string()),
             ],
             ..MetaSchema::ANY
         }