diff --git a/utoipa-gen/src/openapi.rs b/utoipa-gen/src/openapi.rs index db0afcc9..8ba84abf 100644 --- a/utoipa-gen/src/openapi.rs +++ b/utoipa-gen/src/openapi.rs @@ -633,7 +633,7 @@ impl Parse for Components { } } -impl crate::ToTokensDiagnostics for Components { +impl ToTokensDiagnostics for Components { fn to_tokens(&self, tokens: &mut TokenStream) -> Result<(), Diagnostics> { if self.schemas.is_empty() && self.responses.is_empty() { return Ok(()); @@ -659,7 +659,10 @@ impl crate::ToTokensDiagnostics for Components { <#type_path as utoipa::ToSchema>::schemas(&mut schemas); schemas } )}); - components.extend(quote! { .schema(#name, #schema) }); + components.extend(quote! { .schema(#name, { + let mut generics = Vec::>::new(); + #schema + }) }); components }, diff --git a/utoipa-gen/tests/openapi_derive.rs b/utoipa-gen/tests/openapi_derive.rs index 803998b2..78df2398 100644 --- a/utoipa-gen/tests/openapi_derive.rs +++ b/utoipa-gen/tests/openapi_derive.rs @@ -525,3 +525,51 @@ fn openapi_resolvle_recursive_references() { assert_json_snapshot!(schemas); } + +#[test] +fn derive_generic_openapi_component_schemas() { + #[derive(Serialize, ToSchema)] + #[schema(as = dto::page::Response)] + #[serde(rename_all = "camelCase")] + pub struct Response { + pub list: Vec, + pub num: u64, + pub size: u64, + pub total: u64, + } + + pub mod unit { + use serde::Serialize; + use utoipa::ToSchema; + + #[derive(Serialize, ToSchema)] + #[schema(as = dto::get::unit::Response)] + #[serde(rename_all = "camelCase")] + pub struct Response { + pub id: i64, + pub latitude: f64, + pub longitude: f64, + pub title: String, + pub description: Option, + pub country: String, + pub region: Option, + pub city: String, + pub address: String, + } + } + + #[derive(OpenApi)] + #[openapi( + components( + schemas( + Response, + ) + ) + )] + struct ApiDoc; + + let doc = serde_json::to_value(ApiDoc::openapi()).expect("OpenApi is JSON serializable"); + let schemas = doc.pointer("/components"); + + assert_json_snapshot!(schemas) +} diff --git a/utoipa-gen/tests/snapshots/openapi_derive__derive_generic_openapi_component_schemas.snap b/utoipa-gen/tests/snapshots/openapi_derive__derive_generic_openapi_component_schemas.snap new file mode 100644 index 00000000..e1aa679e --- /dev/null +++ b/utoipa-gen/tests/snapshots/openapi_derive__derive_generic_openapi_component_schemas.snap @@ -0,0 +1,41 @@ +--- +source: utoipa-gen/tests/openapi_derive.rs +expression: schemas +snapshot_kind: text +--- +{ + "schemas": { + "dto.page.Response_dto.get.unit.Response": { + "properties": { + "list": { + "items": { + "$ref": "#/components/schemas/dto.get.unit.Response" + }, + "type": "array" + }, + "num": { + "format": "int64", + "minimum": 0, + "type": "integer" + }, + "size": { + "format": "int64", + "minimum": 0, + "type": "integer" + }, + "total": { + "format": "int64", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "list", + "num", + "size", + "total" + ], + "type": "object" + } + } +}