diff --git a/acceptance/generics/src/open_api.expected.json b/acceptance/generics/src/open_api.expected.json index 0ab4dcc..a8addeb 100644 --- a/acceptance/generics/src/open_api.expected.json +++ b/acceptance/generics/src/open_api.expected.json @@ -1,204 +1,301 @@ { - "components": { - "schemas": { - "BorrowedResponse_Person": { - "properties": { - "data": { - "properties": { - "age": { - "format": "int32", - "minimum": 0, - "type": "integer" - }, - "name": { - "type": "string" - } - }, - "required": [ - "name", - "age" - ], - "type": "object" - }, - "status": { - "format": "int32", - "minimum": 0, - "type": "integer" - } - }, - "required": [ - "status", - "data" - ], - "type": "object" - }, - "CombinedResponse_Person": { - "properties": { - "borrowed_response": { - "$ref": "#/components/schemas/BorrowedResponse_Person" - }, - "nested_response": { - "$ref": "#/components/schemas/NestedResponse_Person" - } - }, - "required": [ - "nested_response", - "borrowed_response" - ], - "type": "object" - }, - "NestedResponse_Person": { - "properties": { - "response": { - "$ref": "#/components/schemas/Response_Person" - } - }, - "required": [ - "response" - ], - "type": "object" - }, - "Person": { - "properties": { - "age": { - "format": "int32", - "minimum": 0, - "type": "integer" - }, - "name": { - "type": "string" - } - }, - "required": [ - "name", - "age" - ], - "type": "object" - }, - "Response_Person": { - "properties": { - "data": { - "properties": { - "age": { - "format": "int32", - "minimum": 0, - "type": "integer" - }, - "name": { - "type": "string" - } - }, - "required": [ - "name", - "age" - ], - "type": "object" - }, - "status": { - "format": "int32", - "minimum": 0, - "type": "integer" - } - }, - "required": [ - "status", - "data" - ], - "type": "object" - } - } - }, + "openapi": "3.1.0", "info": { + "title": "Generic Test Api", + "description": "A collection of crates to test utoipauto.", "contact": { "name": "ProbablyClem" }, - "description": "A collection of crates to test utoipauto.", "license": { "name": "MIT OR Apache-2.0" }, - "title": "Generic Test Api", "version": "0.1.0" }, - "openapi": "3.1.0", "paths": { - "/borrowed_persons": { + "/persons": { "get": { - "operationId": "get_borrowed_persons", + "tags": [ + "crate::routes" + ], + "operationId": "get_persons", "responses": { "200": { + "description": "A Response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/BorrowedResponse_Person" + "$ref": "#/components/schemas/Response_Person" } } - }, - "description": "A BorrowedResponse<'static, Person>" + } } - }, - "tags": [ - "crate::routes" - ] + } } }, - "/combined_persons": { + "/nested_persons": { "get": { - "operationId": "get_combined_persons", + "tags": [ + "crate::routes" + ], + "operationId": "get_nested_persons", "responses": { "200": { + "description": "A NestedResponse", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CombinedResponse_Person" + "$ref": "#/components/schemas/NestedResponse_Person" } } - }, - "description": "A CombinedResponse<'static, Person>" + } } - }, - "tags": [ - "crate::routes" - ] + } } }, - "/nested_persons": { + "/borrowed_persons": { "get": { - "operationId": "get_nested_persons", + "tags": [ + "crate::routes" + ], + "operationId": "get_borrowed_persons", "responses": { "200": { + "description": "A BorrowedResponse<'static>", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NestedResponse_Person" + "$ref": "#/components/schemas/BorrowedResponse" } } - }, - "description": "A NestedResponse" + } } - }, + } + } + }, + "/nested_borrowed_persons": { + "get": { "tags": [ "crate::routes" - ] + ], + "operationId": "get_nested_borrowed_persons", + "responses": { + "200": { + "description": "A NestedBorrowedResponse<'static, Person>", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NestedBorrowedResponse_Person" + } + } + } + } + } } }, - "/persons": { + "/combined_persons": { "get": { - "operationId": "get_persons", + "tags": [ + "crate::routes" + ], + "operationId": "get_combined_persons", "responses": { "200": { + "description": "A CombinedResponse<'static, Person>", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Response_Person" + "$ref": "#/components/schemas/CombinedResponse_Person" } } + } + } + } + } + } + }, + "components": { + "schemas": { + "BorrowedResponse": { + "type": "object", + "required": [ + "data", + "additional" + ], + "properties": { + "additional": { + "type": "object", + "additionalProperties": { + "type": "integer", + "format": "int32" }, - "description": "A Response" + "propertyNames": { + "type": "string" + } + }, + "data": { + "type": "string" } - }, - "tags": [ - "crate::routes" - ] + } + }, + "CombinedResponse_Person": { + "type": "object", + "required": [ + "nested_response", + "borrowed_response" + ], + "properties": { + "borrowed_response": { + "$ref": "#/components/schemas/NestedBorrowedResponse_Person" + }, + "nested_response": { + "$ref": "#/components/schemas/NestedResponse_Person" + } + } + }, + "NestedBorrowedResponse_Person": { + "type": "object", + "required": [ + "status", + "data" + ], + "properties": { + "data": { + "type": "object", + "required": [ + "name", + "age" + ], + "properties": { + "age": { + "type": "integer", + "format": "int32", + "minimum": 0 + }, + "name": { + "type": "string" + } + } + }, + "status": { + "type": "integer", + "format": "int32", + "minimum": 0 + } + } + }, + "NestedResponse_Person": { + "type": "object", + "required": [ + "response" + ], + "properties": { + "response": { + "$ref": "#/components/schemas/Response_Person" + } + } + }, + "Person": { + "type": "object", + "required": [ + "name", + "age" + ], + "properties": { + "age": { + "type": "integer", + "format": "int32", + "minimum": 0 + }, + "name": { + "type": "string" + } + } + }, + "Response_Person": { + "type": "object", + "required": [ + "status", + "data" + ], + "properties": { + "data": { + "type": "object", + "required": [ + "name", + "age" + ], + "properties": { + "age": { + "type": "integer", + "format": "int32", + "minimum": 0 + }, + "name": { + "type": "string" + } + } + }, + "status": { + "type": "integer", + "format": "int32", + "minimum": 0 + } + } + } + }, + "responses": { + "BorrowedResponse": { + "description": "", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "data", + "additional" + ], + "properties": { + "additional": { + "type": "object", + "additionalProperties": { + "type": "integer", + "format": "int32" + }, + "propertyNames": { + "type": "string" + } + }, + "data": { + "type": "string" + } + } + } + } + } + }, + "Person": { + "description": "", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "name", + "age" + ], + "properties": { + "age": { + "type": "integer", + "format": "int32", + "minimum": 0 + }, + "name": { + "type": "string" + } + } + } + } + } } } } diff --git a/acceptance/generics/src/routes.rs b/acceptance/generics/src/routes.rs index 84a58f7..6459cef 100644 --- a/acceptance/generics/src/routes.rs +++ b/acceptance/generics/src/routes.rs @@ -1,4 +1,6 @@ -use crate::schemas::{BorrowedResponse, CombinedResponse, NestedResponse, Person, Response}; +use std::collections::HashMap; + +use crate::schemas::{BorrowedResponse, CombinedResponse, NestedBorrowedResponse, NestedResponse, Person, Response}; #[utoipa::path(get, path = "/persons", @@ -37,15 +39,29 @@ pub fn get_nested_persons() -> NestedResponse { #[utoipa::path(get, path = "/borrowed_persons", responses( -(status = 200, description = "A BorrowedResponse<'static, Person>", content_type = "application/json", body = BorrowedResponse<'static, Person>), +(status = 200, description = "A BorrowedResponse<'static>", content_type = "application/json", body = BorrowedResponse<'static>), + ) +)] +pub fn get_borrowed_persons() -> BorrowedResponse<'static> { + let additional = HashMap::from([("first", &42), ("second", &-3)]); + BorrowedResponse { + data: "Test", + additional, + } +} + +#[utoipa::path(get, + path = "/nested_borrowed_persons", + responses( +(status = 200, description = "A NestedBorrowedResponse<'static, Person>", content_type = "application/json", body = NestedBorrowedResponse<'static, Person>), ) )] -pub fn get_borrowed_persons() -> BorrowedResponse<'static, Person> { +pub fn get_nested_borrowed_persons() -> NestedBorrowedResponse<'static, Person> { let person = Box::new(Person { name: "John Doe".to_string(), age: 30, }); - BorrowedResponse { + NestedBorrowedResponse { status: 200, data: Box::leak(person), } @@ -70,7 +86,7 @@ pub fn get_combined_persons() -> CombinedResponse<'static, Person> { data: person_ref.clone(), }, }, - borrowed_response: BorrowedResponse { + borrowed_response: NestedBorrowedResponse { status: 200, data: person_ref, }, diff --git a/acceptance/generics/src/schemas.rs b/acceptance/generics/src/schemas.rs index 22b87fe..523b653 100644 --- a/acceptance/generics/src/schemas.rs +++ b/acceptance/generics/src/schemas.rs @@ -1,33 +1,42 @@ -use utoipa::ToSchema; +use std::collections::HashMap; -#[derive(Debug, ToSchema)] +use utoipa::{ToResponse, ToSchema}; + +#[derive(Debug, ToSchema, ToResponse)] pub struct Response { pub status: u16, pub data: T, } -#[derive(Debug, Clone, ToSchema)] +#[derive(Debug, Clone, ToSchema, ToResponse)] pub struct Person { pub name: String, pub age: u8, } // Nested Generics -#[derive(Debug, ToSchema)] +#[derive(Debug, ToSchema, ToResponse)] pub struct NestedResponse { pub response: Response, } // Lifetime Generics -#[derive(Debug, ToSchema)] -pub struct BorrowedResponse<'a, T: ToSchema> { +#[derive(Debug, ToSchema, ToResponse)] +pub struct BorrowedResponse<'a> { + pub data: &'a str, + pub additional: HashMap<&'a str, &'a i32>, +} + +// Lifetime + nested Generics +#[derive(Debug, ToSchema, ToResponse)] +pub struct NestedBorrowedResponse<'a, T: ToSchema> { pub status: u16, pub data: &'a T, } // Combined Generics -#[derive(Debug, ToSchema)] +#[derive(Debug, ToSchema, ToResponse)] pub struct CombinedResponse<'a, T: ToSchema> { pub nested_response: NestedResponse, - pub borrowed_response: BorrowedResponse<'a, T>, + pub borrowed_response: NestedBorrowedResponse<'a, T>, } diff --git a/utoipauto-core/src/discover.rs b/utoipauto-core/src/discover.rs index 37a4a92..d7150a5 100644 --- a/utoipauto-core/src/discover.rs +++ b/utoipauto-core/src/discover.rs @@ -88,7 +88,7 @@ fn parse_from_attr( params: &Parameters, ) -> Vec { let mut out: Vec = vec![]; - if !generic_params.is_empty() { + if !generic_params.iter().all(|p| matches!(p, GenericParam::Lifetime(_))) { return out; }