juhaku / utoipa

Simple, Fast, Code first and Compile time generated OpenAPI documentation for Rust
Apache License 2.0
2.05k stars 163 forks source link

Aliases for generic enum in body #817

Open javihc opened 7 months ago

javihc commented 7 months ago

I am writting an API with Axum and I am using and enum to recevibe o single value or a list of values. For that I am using a Enum with a generic type T

pub enum OneOrMany<T> {
    /// A single value
    One(T),
    /// A list of values
    Many(Vec<T>),
}

To generate the OpenAPi I use aliases aliases(StringOneOrMany = OneOrMany<String>) and when I generate the openapi.json it serialize as

"StringOneOrMany": {
    "oneOf": [
        {
            "$ref": "#/components/schemas/T"
        },
        {
            "type": "array",
            "items": {
                "$ref": "#/components/schemas/T"
            },
            "description": "A list of values"
        }
    ]
},

How can I generate the schema correctly without using value_type=

pub enum OneOrMany<T> {
    #[schema(value_type = String)]
    /// A single value
    One(T),
    #[schema(value_type = Vec<String>)]
    /// A list of values
    Many(Vec<T>),
}

With schemars the is no problem.

wuerges commented 5 months ago

Hey. In my project, I've implemented the ToSchema trait manually. I added a constraint for T:

impl<'a, T: ToSchema<'a>> ToSchema<'a> for OneOrMany<T> {
    fn schema() -> (
        &'a str,
        utoipa::openapi::RefOr<utoipa::openapi::schema::Schema>,
    ) {
        let (schema_name, schema) = T::schema();
        let object = /* your schema */;

        ("OneOrMany", RefOr::<Schema>::T(Schema::Object(object)))
    }
}