[Rust-Axum][Breaking Change] Implement a customizable error handler (#20463)

* Implement a custom error handler for unhandled or generic endpoint errors

* Pass in method, host and cookies to error handler

* Update axum to 0.8

* Make API methods take references instead of ownership

* Multipart is also part of the axum update

* Prevent replacing path names with the same name as a dynamic path parameter

* Use status code name instead of number

* Rollback axum update

* Forgot paths
This commit is contained in:
Victoria Casasampere Fernandez 2025-02-09 14:54:01 +01:00 committed by GitHub
parent ba0456aa91
commit adbbe68d4d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
81 changed files with 2695 additions and 1649 deletions

View File

@ -62,7 +62,7 @@ tokio = { version = "1", default-features = false, features = [
] } ] }
tracing = { version = "0.1", features = ["attributes"] } tracing = { version = "0.1", features = ["attributes"] }
uuid = { version = "1", features = ["serde"] } uuid = { version = "1", features = ["serde"] }
validator = { version = "0.19", features = ["derive"] } validator = { version = "0.20", features = ["derive"] }
[dev-dependencies] [dev-dependencies]
tracing-subscriber = "0.3" tracing-subscriber = "0.3"

View File

@ -48,16 +48,18 @@ struct ServerImpl {
#[allow(unused_variables)] #[allow(unused_variables)]
#[async_trait] #[async_trait]
impl {{{packageName}}}::Api for ServerImpl { impl {{{externCrateName}}}::apis::default::Api for ServerImpl {
// API implementation goes here // API implementation goes here
} }
impl {{{externCrateName}}}::apis::ErrorHandler for ServerImpl {}
pub async fn start_server(addr: &str) { pub async fn start_server(addr: &str) {
// initialize tracing // initialize tracing
tracing_subscriber::fmt::init(); tracing_subscriber::fmt::init();
// Init Axum router // Init Axum router
let app = {{{packageName}}}::server::new(Arc::new(ServerImpl)); let app = {{{externCrateName}}}::server::new(Arc::new(ServerImpl));
// Add layers to the router // Add layers to the router
let app = app.layer(...); let app = app.layer(...);

View File

@ -28,3 +28,23 @@ pub trait ApiKeyAuthHeader {
{{/isKeyInHeader}} {{/isKeyInHeader}}
{{/isApiKey}} {{/isApiKey}}
{{/authMethods}} {{/authMethods}}
// Error handler for unhandled errors.
#[async_trait::async_trait]
pub trait ErrorHandler<E: std::fmt::Debug + Send + Sync + 'static = ()> {
#[allow(unused_variables)]
#[tracing::instrument(skip_all)]
async fn handle_error(
&self,
method: &::http::Method,
host: &axum::extract::Host,
cookies: &axum_extra::extract::CookieJar,
error: E
) -> Result<axum::response::Response, http::StatusCode> {
tracing::error!("Unhandled error: {:?}", error);
axum::response::Response::builder()
.status(http::StatusCode::INTERNAL_SERVER_ERROR)
.body(axum::body::Body::empty())
.map_err(|_| http::StatusCode::INTERNAL_SERVER_ERROR)
}
}

View File

@ -17,7 +17,7 @@ use crate::{models, types::*};
/// {{classnamePascalCase}} /// {{classnamePascalCase}}
#[async_trait] #[async_trait]
#[allow(clippy::ptr_arg)] #[allow(clippy::ptr_arg)]
pub trait {{classnamePascalCase}} { pub trait {{classnamePascalCase}}<E: std::fmt::Debug + Send + Sync + 'static = ()>: super::ErrorHandler<E> {
{{#havingAuthMethod}} {{#havingAuthMethod}}
type Claims; type Claims;
@ -31,36 +31,36 @@ pub trait {{classnamePascalCase}} {
/// {{{operationId}}} - {{{httpMethod}}} {{{basePathWithoutHost}}}{{{path}}} /// {{{operationId}}} - {{{httpMethod}}} {{{basePathWithoutHost}}}{{{path}}}
async fn {{{x-operation-id}}}( async fn {{{x-operation-id}}}(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
{{#vendorExtensions}} {{#vendorExtensions}}
{{#x-has-auth-methods}} {{#x-has-auth-methods}}
claims: Self::Claims, claims: &Self::Claims,
{{/x-has-auth-methods}} {{/x-has-auth-methods}}
{{/vendorExtensions}} {{/vendorExtensions}}
{{#headerParams.size}} {{#headerParams.size}}
header_params: models::{{{operationIdCamelCase}}}HeaderParams, header_params: &models::{{{operationIdCamelCase}}}HeaderParams,
{{/headerParams.size}} {{/headerParams.size}}
{{#pathParams.size}} {{#pathParams.size}}
path_params: models::{{{operationIdCamelCase}}}PathParams, path_params: &models::{{{operationIdCamelCase}}}PathParams,
{{/pathParams.size}} {{/pathParams.size}}
{{#queryParams.size}} {{#queryParams.size}}
query_params: models::{{{operationIdCamelCase}}}QueryParams, query_params: &models::{{{operationIdCamelCase}}}QueryParams,
{{/queryParams.size}} {{/queryParams.size}}
{{^x-consumes-multipart-related}} {{^x-consumes-multipart-related}}
{{^x-consumes-multipart}} {{^x-consumes-multipart}}
{{#bodyParam}} {{#bodyParam}}
{{#vendorExtensions}} {{#vendorExtensions}}
{{^x-consumes-plain-text}} {{^x-consumes-plain-text}}
body: {{^required}}Option<{{/required}}{{{dataType}}}{{^required}}>{{/required}}, body: &{{^required}}Option<{{/required}}{{{dataType}}}{{^required}}>{{/required}},
{{/x-consumes-plain-text}} {{/x-consumes-plain-text}}
{{#x-consumes-plain-text}} {{#x-consumes-plain-text}}
{{#isString}} {{#isString}}
body: String, body: &String,
{{/isString}} {{/isString}}
{{^isString}} {{^isString}}
body: Bytes, body: &Bytes,
{{/isString}} {{/isString}}
{{/x-consumes-plain-text}} {{/x-consumes-plain-text}}
{{/vendorExtensions}} {{/vendorExtensions}}
@ -68,12 +68,12 @@ pub trait {{classnamePascalCase}} {
{{/x-consumes-multipart}} {{/x-consumes-multipart}}
{{/x-consumes-multipart-related}} {{/x-consumes-multipart-related}}
{{#x-consumes-multipart}} {{#x-consumes-multipart}}
body: Multipart, body: &Multipart,
{{/x-consumes-multipart}} {{/x-consumes-multipart}}
{{#x-consumes-multipart-related}} {{#x-consumes-multipart-related}}
body: axum::body::Body, body: &axum::body::Body,
{{/x-consumes-multipart-related}} {{/x-consumes-multipart-related}}
) -> Result<{{{operationId}}}Response, ()>; ) -> Result<{{{operationId}}}Response, E>;
{{/vendorExtensions}} {{/vendorExtensions}}
{{^-last}} {{^-last}}

View File

@ -1,6 +1,6 @@
/// {{{operationId}}} - {{{httpMethod}}} {{{basePathWithoutHost}}}{{{path}}} /// {{{operationId}}} - {{{httpMethod}}} {{{basePathWithoutHost}}}{{{path}}}
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
async fn {{#vendorExtensions}}{{{x-operation-id}}}{{/vendorExtensions}}<I, A{{#havingAuthMethod}}, C{{/havingAuthMethod}}>( async fn {{#vendorExtensions}}{{{x-operation-id}}}{{/vendorExtensions}}<I, A, E{{#havingAuthMethod}}, C{{/havingAuthMethod}}>(
method: Method, method: Method,
host: Host, host: Host,
cookies: CookieJar, cookies: CookieJar,
@ -54,7 +54,8 @@ async fn {{#vendorExtensions}}{{{x-operation-id}}}{{/vendorExtensions}}<I, A{{#h
) -> Result<Response, StatusCode> ) -> Result<Response, StatusCode>
where where
I: AsRef<A> + Send + Sync, I: AsRef<A> + Send + Sync,
A: apis::{{classFilename}}::{{classnamePascalCase}}{{#havingAuthMethod}}<Claims = C>{{/havingAuthMethod}}{{#vendorExtensions}}{{#x-has-cookie-auth-methods}}+ apis::CookieAuthentication<Claims = C>{{/x-has-cookie-auth-methods}}{{#x-has-header-auth-methods}}+ apis::ApiKeyAuthHeader<Claims = C>{{/x-has-header-auth-methods}}{{/vendorExtensions}}, A: apis::{{classFilename}}::{{classnamePascalCase}}<E{{#havingAuthMethod}}, Claims = C{{/havingAuthMethod}}>{{#vendorExtensions}}{{#x-has-cookie-auth-methods}}+ apis::CookieAuthentication<Claims = C>{{/x-has-cookie-auth-methods}}{{#x-has-header-auth-methods}}+ apis::ApiKeyAuthHeader<Claims = C>{{/x-has-header-auth-methods}}{{/vendorExtensions}} + Send + Sync,
E: std::fmt::Debug + Send + Sync + 'static,
{ {
{{#vendorExtensions}} {{#vendorExtensions}}
{{#x-has-auth-methods}} {{#x-has-auth-methods}}
@ -186,38 +187,38 @@ where
{{/disableValidator}} {{/disableValidator}}
let result = api_impl.as_ref().{{#vendorExtensions}}{{{x-operation-id}}}{{/vendorExtensions}}( let result = api_impl.as_ref().{{#vendorExtensions}}{{{x-operation-id}}}{{/vendorExtensions}}(
method, &method,
host, &host,
cookies, &cookies,
{{#vendorExtensions}} {{#vendorExtensions}}
{{#x-has-auth-methods}} {{#x-has-auth-methods}}
claims, &claims,
{{/x-has-auth-methods}} {{/x-has-auth-methods}}
{{/vendorExtensions}} {{/vendorExtensions}}
{{#headerParams.size}} {{#headerParams.size}}
header_params, &header_params,
{{/headerParams.size}} {{/headerParams.size}}
{{#pathParams.size}} {{#pathParams.size}}
path_params, &path_params,
{{/pathParams.size}} {{/pathParams.size}}
{{#queryParams.size}} {{#queryParams.size}}
query_params, &query_params,
{{/queryParams.size}} {{/queryParams.size}}
{{#vendorExtensions}} {{#vendorExtensions}}
{{^x-consumes-multipart-related}} {{^x-consumes-multipart-related}}
{{^x-consumes-multipart}} {{^x-consumes-multipart}}
{{#bodyParams}} {{#bodyParams}}
{{#-first}} {{#-first}}
body, &body,
{{/-first}} {{/-first}}
{{/bodyParams}} {{/bodyParams}}
{{/x-consumes-multipart}} {{/x-consumes-multipart}}
{{/x-consumes-multipart-related}} {{/x-consumes-multipart-related}}
{{#x-consumes-multipart}} {{#x-consumes-multipart}}
body, &body,
{{/x-consumes-multipart}} {{/x-consumes-multipart}}
{{#x-consumes-multipart-related}} {{#x-consumes-multipart-related}}
body, &body,
{{/x-consumes-multipart-related}} {{/x-consumes-multipart-related}}
{{/vendorExtensions}} {{/vendorExtensions}}
).await; ).await;
@ -342,10 +343,11 @@ where
}, },
{{/responses}} {{/responses}}
}, },
Err(_) => { Err(why) => {
// Application code returned an error. This should not happen, as the implementation should // Application code returned an error. This should not happen, as the implementation should
// return a valid response. // return a valid response.
response.status(500).body(Body::empty())
return api_impl.as_ref().handle_error(&method, &host, &cookies, why).await;
}, },
}; };

View File

@ -1,15 +1,16 @@
/// Setup API Server. /// Setup API Server.
pub fn new<I, A{{#havingAuthMethods}}, C{{/havingAuthMethods}}>(api_impl: I) -> Router pub fn new<I, A, E{{#havingAuthMethods}}, C{{/havingAuthMethods}}>(api_impl: I) -> Router
where where
I: AsRef<A> + Clone + Send + Sync + 'static, I: AsRef<A> + Clone + Send + Sync + 'static,
A: {{#apiInfo}}{{#apis}}{{#operations}}apis::{{classFilename}}::{{classnamePascalCase}}{{#havingAuthMethod}}<Claims = C>{{/havingAuthMethod}} + {{/operations}}{{/apis}}{{/apiInfo}}{{#authMethods}}{{#isApiKey}}{{#isKeyInCookie}}apis::CookieAuthentication<Claims = C> + {{/isKeyInCookie}}{{#isKeyInHeader}}apis::ApiKeyAuthHeader<Claims = C> + {{/isKeyInHeader}}{{/isApiKey}}{{/authMethods}}'static, A: {{#apiInfo}}{{#apis}}{{#operations}}apis::{{classFilename}}::{{classnamePascalCase}}<E{{#havingAuthMethod}}, Claims = C{{/havingAuthMethod}}> + {{/operations}}{{/apis}}{{/apiInfo}}{{#authMethods}}{{#isApiKey}}{{#isKeyInCookie}}apis::CookieAuthentication<Claims = C> + {{/isKeyInCookie}}{{#isKeyInHeader}}apis::ApiKeyAuthHeader<Claims = C> + {{/isKeyInHeader}}{{/isApiKey}}{{/authMethods}}Send + Sync + 'static,
E: std::fmt::Debug + Send + Sync + 'static,
{{#havingAuthMethods}}C: Send + Sync + 'static,{{/havingAuthMethods}} {{#havingAuthMethods}}C: Send + Sync + 'static,{{/havingAuthMethods}}
{ {
// build our application with a route // build our application with a route
Router::new() Router::new()
{{#pathMethodOps}} {{#pathMethodOps}}
.route("{{{basePathWithoutHost}}}{{{path}}}", .route("{{{basePathWithoutHost}}}{{{path}}}",
{{#methodOperations}}{{{method}}}({{{operationID}}}::<I, A{{#vendorExtensions}}{{#havingAuthMethod}}, C{{/havingAuthMethod}}{{/vendorExtensions}}>){{^-last}}.{{/-last}}{{/methodOperations}} {{#methodOperations}}{{{method}}}({{{operationID}}}::<I, A, E{{#vendorExtensions}}{{#havingAuthMethod}}, C{{/havingAuthMethod}}{{/vendorExtensions}}>){{^-last}}.{{/-last}}{{/methodOperations}}
) )
{{/pathMethodOps}} {{/pathMethodOps}}
.with_state(api_impl) .with_state(api_impl)

View File

@ -1 +1 @@
7.11.0-SNAPSHOT 7.12.0-SNAPSHOT

View File

@ -40,7 +40,7 @@ tokio = { version = "1", default-features = false, features = [
] } ] }
tracing = { version = "0.1", features = ["attributes"] } tracing = { version = "0.1", features = ["attributes"] }
uuid = { version = "1", features = ["serde"] } uuid = { version = "1", features = ["serde"] }
validator = { version = "0.19", features = ["derive"] } validator = { version = "0.20", features = ["derive"] }
[dev-dependencies] [dev-dependencies]
tracing-subscriber = "0.3" tracing-subscriber = "0.3"

View File

@ -12,7 +12,7 @@ server, you can easily generate a server stub.
To see how to make this your own, look here: [README]((https://openapi-generator.tech)) To see how to make this your own, look here: [README]((https://openapi-generator.tech))
- API version: 1.0.0 - API version: 1.0.0
- Generator version: 7.11.0-SNAPSHOT - Generator version: 7.12.0-SNAPSHOT
@ -43,16 +43,18 @@ struct ServerImpl {
#[allow(unused_variables)] #[allow(unused_variables)]
#[async_trait] #[async_trait]
impl apikey-auths::Api for ServerImpl { impl apikey_auths::apis::default::Api for ServerImpl {
// API implementation goes here // API implementation goes here
} }
impl apikey_auths::apis::ErrorHandler for ServerImpl {}
pub async fn start_server(addr: &str) { pub async fn start_server(addr: &str) {
// initialize tracing // initialize tracing
tracing_subscriber::fmt::init(); tracing_subscriber::fmt::init();
// Init Axum router // Init Axum router
let app = apikey-auths::server::new(Arc::new(ServerImpl)); let app = apikey_auths::server::new(Arc::new(ServerImpl));
// Add layers to the router // Add layers to the router
let app = app.layer(...); let app = app.layer(...);

View File

@ -24,3 +24,23 @@ pub trait CookieAuthentication {
key: &str, key: &str,
) -> Option<Self::Claims>; ) -> Option<Self::Claims>;
} }
// Error handler for unhandled errors.
#[async_trait::async_trait]
pub trait ErrorHandler<E: std::fmt::Debug + Send + Sync + 'static = ()> {
#[allow(unused_variables)]
#[tracing::instrument(skip_all)]
async fn handle_error(
&self,
method: &::http::Method,
host: &axum::extract::Host,
cookies: &axum_extra::extract::CookieJar,
error: E,
) -> Result<axum::response::Response, http::StatusCode> {
tracing::error!("Unhandled error: {:?}", error);
axum::response::Response::builder()
.status(http::StatusCode::INTERNAL_SERVER_ERROR)
.body(axum::body::Body::empty())
.map_err(|_| http::StatusCode::INTERNAL_SERVER_ERROR)
}
}

View File

@ -38,7 +38,9 @@ pub enum PostMakePaymentResponse {
/// Payments /// Payments
#[async_trait] #[async_trait]
#[allow(clippy::ptr_arg)] #[allow(clippy::ptr_arg)]
pub trait Payments { pub trait Payments<E: std::fmt::Debug + Send + Sync + 'static = ()>:
super::ErrorHandler<E>
{
type Claims; type Claims;
/// Get payment method by id. /// Get payment method by id.
@ -46,31 +48,31 @@ pub trait Payments {
/// GetPaymentMethodById - GET /v71/paymentMethods/{id} /// GetPaymentMethodById - GET /v71/paymentMethods/{id}
async fn get_payment_method_by_id( async fn get_payment_method_by_id(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
path_params: models::GetPaymentMethodByIdPathParams, path_params: &models::GetPaymentMethodByIdPathParams,
) -> Result<GetPaymentMethodByIdResponse, ()>; ) -> Result<GetPaymentMethodByIdResponse, E>;
/// Get payment methods. /// Get payment methods.
/// ///
/// GetPaymentMethods - GET /v71/paymentMethods /// GetPaymentMethods - GET /v71/paymentMethods
async fn get_payment_methods( async fn get_payment_methods(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<GetPaymentMethodsResponse, ()>; ) -> Result<GetPaymentMethodsResponse, E>;
/// Make a payment. /// Make a payment.
/// ///
/// PostMakePayment - POST /v71/payments /// PostMakePayment - POST /v71/payments
async fn post_make_payment( async fn post_make_payment(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
claims: Self::Claims, claims: &Self::Claims,
body: Option<models::Payment>, body: &Option<models::Payment>,
) -> Result<PostMakePaymentResponse, ()>; ) -> Result<PostMakePaymentResponse, E>;
} }

View File

@ -13,23 +13,29 @@ use crate::{header, types::*};
use crate::{apis, models}; use crate::{apis, models};
/// Setup API Server. /// Setup API Server.
pub fn new<I, A, C>(api_impl: I) -> Router pub fn new<I, A, E, C>(api_impl: I) -> Router
where where
I: AsRef<A> + Clone + Send + Sync + 'static, I: AsRef<A> + Clone + Send + Sync + 'static,
A: apis::payments::Payments<Claims = C> A: apis::payments::Payments<E, Claims = C>
+ apis::ApiKeyAuthHeader<Claims = C> + apis::ApiKeyAuthHeader<Claims = C>
+ apis::CookieAuthentication<Claims = C> + apis::CookieAuthentication<Claims = C>
+ Send
+ Sync
+ 'static, + 'static,
E: std::fmt::Debug + Send + Sync + 'static,
C: Send + Sync + 'static, C: Send + Sync + 'static,
{ {
// build our application with a route // build our application with a route
Router::new() Router::new()
.route("/v71/paymentMethods", get(get_payment_methods::<I, A, C>)) .route(
"/v71/paymentMethods",
get(get_payment_methods::<I, A, E, C>),
)
.route( .route(
"/v71/paymentMethods/:id", "/v71/paymentMethods/:id",
get(get_payment_method_by_id::<I, A, C>), get(get_payment_method_by_id::<I, A, E, C>),
) )
.route("/v71/payments", post(post_make_payment::<I, A, C>)) .route("/v71/payments", post(post_make_payment::<I, A, E, C>))
.with_state(api_impl) .with_state(api_impl)
} }
@ -43,7 +49,7 @@ fn get_payment_method_by_id_validation(
} }
/// GetPaymentMethodById - GET /v71/paymentMethods/{id} /// GetPaymentMethodById - GET /v71/paymentMethods/{id}
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
async fn get_payment_method_by_id<I, A, C>( async fn get_payment_method_by_id<I, A, E, C>(
method: Method, method: Method,
host: Host, host: Host,
cookies: CookieJar, cookies: CookieJar,
@ -52,7 +58,8 @@ async fn get_payment_method_by_id<I, A, C>(
) -> Result<Response, StatusCode> ) -> Result<Response, StatusCode>
where where
I: AsRef<A> + Send + Sync, I: AsRef<A> + Send + Sync,
A: apis::payments::Payments<Claims = C>, A: apis::payments::Payments<E, Claims = C> + Send + Sync,
E: std::fmt::Debug + Send + Sync + 'static,
{ {
#[allow(clippy::redundant_closure)] #[allow(clippy::redundant_closure)]
let validation = let validation =
@ -69,7 +76,7 @@ where
let result = api_impl let result = api_impl
.as_ref() .as_ref()
.get_payment_method_by_id(method, host, cookies, path_params) .get_payment_method_by_id(&method, &host, &cookies, &path_params)
.await; .await;
let mut response = Response::builder(); let mut response = Response::builder();
@ -123,10 +130,14 @@ where
response.body(Body::from(body_content)) response.body(Body::from(body_content))
} }
}, },
Err(_) => { Err(why) => {
// Application code returned an error. This should not happen, as the implementation should // Application code returned an error. This should not happen, as the implementation should
// return a valid response. // return a valid response.
response.status(500).body(Body::empty())
return api_impl
.as_ref()
.handle_error(&method, &host, &cookies, why)
.await;
} }
}; };
@ -142,7 +153,7 @@ fn get_payment_methods_validation() -> std::result::Result<(), ValidationErrors>
} }
/// GetPaymentMethods - GET /v71/paymentMethods /// GetPaymentMethods - GET /v71/paymentMethods
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
async fn get_payment_methods<I, A, C>( async fn get_payment_methods<I, A, E, C>(
method: Method, method: Method,
host: Host, host: Host,
cookies: CookieJar, cookies: CookieJar,
@ -150,7 +161,8 @@ async fn get_payment_methods<I, A, C>(
) -> Result<Response, StatusCode> ) -> Result<Response, StatusCode>
where where
I: AsRef<A> + Send + Sync, I: AsRef<A> + Send + Sync,
A: apis::payments::Payments<Claims = C>, A: apis::payments::Payments<E, Claims = C> + Send + Sync,
E: std::fmt::Debug + Send + Sync + 'static,
{ {
#[allow(clippy::redundant_closure)] #[allow(clippy::redundant_closure)]
let validation = tokio::task::spawn_blocking(move || get_payment_methods_validation()) let validation = tokio::task::spawn_blocking(move || get_payment_methods_validation())
@ -166,7 +178,7 @@ where
let result = api_impl let result = api_impl
.as_ref() .as_ref()
.get_payment_methods(method, host, cookies) .get_payment_methods(&method, &host, &cookies)
.await; .await;
let mut response = Response::builder(); let mut response = Response::builder();
@ -197,10 +209,14 @@ where
response.body(Body::from(body_content)) response.body(Body::from(body_content))
} }
}, },
Err(_) => { Err(why) => {
// Application code returned an error. This should not happen, as the implementation should // Application code returned an error. This should not happen, as the implementation should
// return a valid response. // return a valid response.
response.status(500).body(Body::empty())
return api_impl
.as_ref()
.handle_error(&method, &host, &cookies, why)
.await;
} }
}; };
@ -230,7 +246,7 @@ fn post_make_payment_validation(
} }
/// PostMakePayment - POST /v71/payments /// PostMakePayment - POST /v71/payments
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
async fn post_make_payment<I, A, C>( async fn post_make_payment<I, A, E, C>(
method: Method, method: Method,
host: Host, host: Host,
cookies: CookieJar, cookies: CookieJar,
@ -239,7 +255,11 @@ async fn post_make_payment<I, A, C>(
) -> Result<Response, StatusCode> ) -> Result<Response, StatusCode>
where where
I: AsRef<A> + Send + Sync, I: AsRef<A> + Send + Sync,
A: apis::payments::Payments<Claims = C> + apis::CookieAuthentication<Claims = C>, A: apis::payments::Payments<E, Claims = C>
+ apis::CookieAuthentication<Claims = C>
+ Send
+ Sync,
E: std::fmt::Debug + Send + Sync + 'static,
{ {
// Authentication // Authentication
let claims_in_cookie = api_impl let claims_in_cookie = api_impl
@ -268,7 +288,7 @@ where
let result = api_impl let result = api_impl
.as_ref() .as_ref()
.post_make_payment(method, host, cookies, claims, body) .post_make_payment(&method, &host, &cookies, &claims, &body)
.await; .await;
let mut response = Response::builder(); let mut response = Response::builder();
@ -322,10 +342,14 @@ where
response.body(Body::from(body_content)) response.body(Body::from(body_content))
} }
}, },
Err(_) => { Err(why) => {
// Application code returned an error. This should not happen, as the implementation should // Application code returned an error. This should not happen, as the implementation should
// return a valid response. // return a valid response.
response.status(500).body(Body::empty())
return api_impl
.as_ref()
.handle_error(&method, &host, &cookies, why)
.await;
} }
}; };

View File

@ -1 +1 @@
7.11.0-SNAPSHOT 7.12.0-SNAPSHOT

View File

@ -40,7 +40,7 @@ tokio = { version = "1", default-features = false, features = [
] } ] }
tracing = { version = "0.1", features = ["attributes"] } tracing = { version = "0.1", features = ["attributes"] }
uuid = { version = "1", features = ["serde"] } uuid = { version = "1", features = ["serde"] }
validator = { version = "0.19", features = ["derive"] } validator = { version = "0.20", features = ["derive"] }
[dev-dependencies] [dev-dependencies]
tracing-subscriber = "0.3" tracing-subscriber = "0.3"

View File

@ -12,7 +12,7 @@ server, you can easily generate a server stub.
To see how to make this your own, look here: [README]((https://openapi-generator.tech)) To see how to make this your own, look here: [README]((https://openapi-generator.tech))
- API version: 1.0.7 - API version: 1.0.7
- Generator version: 7.11.0-SNAPSHOT - Generator version: 7.12.0-SNAPSHOT
@ -43,16 +43,18 @@ struct ServerImpl {
#[allow(unused_variables)] #[allow(unused_variables)]
#[async_trait] #[async_trait]
impl multipart-v3::Api for ServerImpl { impl multipart_v3::apis::default::Api for ServerImpl {
// API implementation goes here // API implementation goes here
} }
impl multipart_v3::apis::ErrorHandler for ServerImpl {}
pub async fn start_server(addr: &str) { pub async fn start_server(addr: &str) {
// initialize tracing // initialize tracing
tracing_subscriber::fmt::init(); tracing_subscriber::fmt::init();
// Init Axum router // Init Axum router
let app = multipart-v3::server::new(Arc::new(ServerImpl)); let app = multipart_v3::server::new(Arc::new(ServerImpl));
// Add layers to the router // Add layers to the router
let app = app.layer(...); let app = app.layer(...);

View File

@ -34,31 +34,31 @@ pub enum MultipleIdenticalMimeTypesPostResponse {
/// Default /// Default
#[async_trait] #[async_trait]
#[allow(clippy::ptr_arg)] #[allow(clippy::ptr_arg)]
pub trait Default { pub trait Default<E: std::fmt::Debug + Send + Sync + 'static = ()>: super::ErrorHandler<E> {
/// MultipartRelatedRequestPost - POST /multipart_related_request /// MultipartRelatedRequestPost - POST /multipart_related_request
async fn multipart_related_request_post( async fn multipart_related_request_post(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
body: axum::body::Body, body: &axum::body::Body,
) -> Result<MultipartRelatedRequestPostResponse, ()>; ) -> Result<MultipartRelatedRequestPostResponse, E>;
/// MultipartRequestPost - POST /multipart_request /// MultipartRequestPost - POST /multipart_request
async fn multipart_request_post( async fn multipart_request_post(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
body: Multipart, body: &Multipart,
) -> Result<MultipartRequestPostResponse, ()>; ) -> Result<MultipartRequestPostResponse, E>;
/// MultipleIdenticalMimeTypesPost - POST /multiple-identical-mime-types /// MultipleIdenticalMimeTypesPost - POST /multiple-identical-mime-types
async fn multiple_identical_mime_types_post( async fn multiple_identical_mime_types_post(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
body: axum::body::Body, body: &axum::body::Body,
) -> Result<MultipleIdenticalMimeTypesPostResponse, ()>; ) -> Result<MultipleIdenticalMimeTypesPostResponse, E>;
} }

View File

@ -1 +1,21 @@
pub mod default; pub mod default;
// Error handler for unhandled errors.
#[async_trait::async_trait]
pub trait ErrorHandler<E: std::fmt::Debug + Send + Sync + 'static = ()> {
#[allow(unused_variables)]
#[tracing::instrument(skip_all)]
async fn handle_error(
&self,
method: &::http::Method,
host: &axum::extract::Host,
cookies: &axum_extra::extract::CookieJar,
error: E,
) -> Result<axum::response::Response, http::StatusCode> {
tracing::error!("Unhandled error: {:?}", error);
axum::response::Response::builder()
.status(http::StatusCode::INTERNAL_SERVER_ERROR)
.body(axum::body::Body::empty())
.map_err(|_| http::StatusCode::INTERNAL_SERVER_ERROR)
}
}

View File

@ -13,21 +13,25 @@ use crate::{header, types::*};
use crate::{apis, models}; use crate::{apis, models};
/// Setup API Server. /// Setup API Server.
pub fn new<I, A>(api_impl: I) -> Router pub fn new<I, A, E>(api_impl: I) -> Router
where where
I: AsRef<A> + Clone + Send + Sync + 'static, I: AsRef<A> + Clone + Send + Sync + 'static,
A: apis::default::Default + 'static, A: apis::default::Default<E> + Send + Sync + 'static,
E: std::fmt::Debug + Send + Sync + 'static,
{ {
// build our application with a route // build our application with a route
Router::new() Router::new()
.route( .route(
"/multipart_related_request", "/multipart_related_request",
post(multipart_related_request_post::<I, A>), post(multipart_related_request_post::<I, A, E>),
)
.route(
"/multipart_request",
post(multipart_request_post::<I, A, E>),
) )
.route("/multipart_request", post(multipart_request_post::<I, A>))
.route( .route(
"/multiple-identical-mime-types", "/multiple-identical-mime-types",
post(multiple_identical_mime_types_post::<I, A>), post(multiple_identical_mime_types_post::<I, A, E>),
) )
.with_state(api_impl) .with_state(api_impl)
} }
@ -38,7 +42,7 @@ fn multipart_related_request_post_validation() -> std::result::Result<(), Valida
} }
/// MultipartRelatedRequestPost - POST /multipart_related_request /// MultipartRelatedRequestPost - POST /multipart_related_request
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
async fn multipart_related_request_post<I, A>( async fn multipart_related_request_post<I, A, E>(
method: Method, method: Method,
host: Host, host: Host,
cookies: CookieJar, cookies: CookieJar,
@ -47,7 +51,8 @@ async fn multipart_related_request_post<I, A>(
) -> Result<Response, StatusCode> ) -> Result<Response, StatusCode>
where where
I: AsRef<A> + Send + Sync, I: AsRef<A> + Send + Sync,
A: apis::default::Default, A: apis::default::Default<E> + Send + Sync,
E: std::fmt::Debug + Send + Sync + 'static,
{ {
#[allow(clippy::redundant_closure)] #[allow(clippy::redundant_closure)]
let validation = let validation =
@ -64,7 +69,7 @@ where
let result = api_impl let result = api_impl
.as_ref() .as_ref()
.multipart_related_request_post(method, host, cookies, body) .multipart_related_request_post(&method, &host, &cookies, &body)
.await; .await;
let mut response = Response::builder(); let mut response = Response::builder();
@ -76,10 +81,14 @@ where
response.body(Body::empty()) response.body(Body::empty())
} }
}, },
Err(_) => { Err(why) => {
// Application code returned an error. This should not happen, as the implementation should // Application code returned an error. This should not happen, as the implementation should
// return a valid response. // return a valid response.
response.status(500).body(Body::empty())
return api_impl
.as_ref()
.handle_error(&method, &host, &cookies, why)
.await;
} }
}; };
@ -95,7 +104,7 @@ fn multipart_request_post_validation() -> std::result::Result<(), ValidationErro
} }
/// MultipartRequestPost - POST /multipart_request /// MultipartRequestPost - POST /multipart_request
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
async fn multipart_request_post<I, A>( async fn multipart_request_post<I, A, E>(
method: Method, method: Method,
host: Host, host: Host,
cookies: CookieJar, cookies: CookieJar,
@ -104,7 +113,8 @@ async fn multipart_request_post<I, A>(
) -> Result<Response, StatusCode> ) -> Result<Response, StatusCode>
where where
I: AsRef<A> + Send + Sync, I: AsRef<A> + Send + Sync,
A: apis::default::Default, A: apis::default::Default<E> + Send + Sync,
E: std::fmt::Debug + Send + Sync + 'static,
{ {
#[allow(clippy::redundant_closure)] #[allow(clippy::redundant_closure)]
let validation = tokio::task::spawn_blocking(move || multipart_request_post_validation()) let validation = tokio::task::spawn_blocking(move || multipart_request_post_validation())
@ -120,7 +130,7 @@ where
let result = api_impl let result = api_impl
.as_ref() .as_ref()
.multipart_request_post(method, host, cookies, body) .multipart_request_post(&method, &host, &cookies, &body)
.await; .await;
let mut response = Response::builder(); let mut response = Response::builder();
@ -132,10 +142,14 @@ where
response.body(Body::empty()) response.body(Body::empty())
} }
}, },
Err(_) => { Err(why) => {
// Application code returned an error. This should not happen, as the implementation should // Application code returned an error. This should not happen, as the implementation should
// return a valid response. // return a valid response.
response.status(500).body(Body::empty())
return api_impl
.as_ref()
.handle_error(&method, &host, &cookies, why)
.await;
} }
}; };
@ -151,7 +165,7 @@ fn multiple_identical_mime_types_post_validation() -> std::result::Result<(), Va
} }
/// MultipleIdenticalMimeTypesPost - POST /multiple-identical-mime-types /// MultipleIdenticalMimeTypesPost - POST /multiple-identical-mime-types
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
async fn multiple_identical_mime_types_post<I, A>( async fn multiple_identical_mime_types_post<I, A, E>(
method: Method, method: Method,
host: Host, host: Host,
cookies: CookieJar, cookies: CookieJar,
@ -160,7 +174,8 @@ async fn multiple_identical_mime_types_post<I, A>(
) -> Result<Response, StatusCode> ) -> Result<Response, StatusCode>
where where
I: AsRef<A> + Send + Sync, I: AsRef<A> + Send + Sync,
A: apis::default::Default, A: apis::default::Default<E> + Send + Sync,
E: std::fmt::Debug + Send + Sync + 'static,
{ {
#[allow(clippy::redundant_closure)] #[allow(clippy::redundant_closure)]
let validation = let validation =
@ -177,7 +192,7 @@ where
let result = api_impl let result = api_impl
.as_ref() .as_ref()
.multiple_identical_mime_types_post(method, host, cookies, body) .multiple_identical_mime_types_post(&method, &host, &cookies, &body)
.await; .await;
let mut response = Response::builder(); let mut response = Response::builder();
@ -189,10 +204,14 @@ where
response.body(Body::empty()) response.body(Body::empty())
} }
}, },
Err(_) => { Err(why) => {
// Application code returned an error. This should not happen, as the implementation should // Application code returned an error. This should not happen, as the implementation should
// return a valid response. // return a valid response.
response.status(500).body(Body::empty())
return api_impl
.as_ref()
.handle_error(&method, &host, &cookies, why)
.await;
} }
}; };

View File

@ -1 +1 @@
7.11.0-SNAPSHOT 7.12.0-SNAPSHOT

View File

@ -40,7 +40,7 @@ tokio = { version = "1", default-features = false, features = [
] } ] }
tracing = { version = "0.1", features = ["attributes"] } tracing = { version = "0.1", features = ["attributes"] }
uuid = { version = "1", features = ["serde"] } uuid = { version = "1", features = ["serde"] }
validator = { version = "0.19", features = ["derive"] } validator = { version = "0.20", features = ["derive"] }
[dev-dependencies] [dev-dependencies]
tracing-subscriber = "0.3" tracing-subscriber = "0.3"

View File

@ -12,7 +12,7 @@ server, you can easily generate a server stub.
To see how to make this your own, look here: [README]((https://openapi-generator.tech)) To see how to make this your own, look here: [README]((https://openapi-generator.tech))
- API version: 1.0.7 - API version: 1.0.7
- Generator version: 7.11.0-SNAPSHOT - Generator version: 7.12.0-SNAPSHOT
@ -43,16 +43,18 @@ struct ServerImpl {
#[allow(unused_variables)] #[allow(unused_variables)]
#[async_trait] #[async_trait]
impl openapi-v3::Api for ServerImpl { impl openapi_v3::apis::default::Api for ServerImpl {
// API implementation goes here // API implementation goes here
} }
impl openapi_v3::apis::ErrorHandler for ServerImpl {}
pub async fn start_server(addr: &str) { pub async fn start_server(addr: &str) {
// initialize tracing // initialize tracing
tracing_subscriber::fmt::init(); tracing_subscriber::fmt::init();
// Init Axum router // Init Axum router
let app = openapi-v3::server::new(Arc::new(ServerImpl)); let app = openapi_v3::server::new(Arc::new(ServerImpl));
// Add layers to the router // Add layers to the router
let app = app.layer(...); let app = app.layer(...);

View File

@ -274,255 +274,255 @@ pub enum XmlPutResponse {
/// Default /// Default
#[async_trait] #[async_trait]
#[allow(clippy::ptr_arg)] #[allow(clippy::ptr_arg)]
pub trait Default { pub trait Default<E: std::fmt::Debug + Send + Sync + 'static = ()>: super::ErrorHandler<E> {
/// AnyOfGet - GET /any-of /// AnyOfGet - GET /any-of
async fn any_of_get( async fn any_of_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
query_params: models::AnyOfGetQueryParams, query_params: &models::AnyOfGetQueryParams,
) -> Result<AnyOfGetResponse, ()>; ) -> Result<AnyOfGetResponse, E>;
/// CallbackWithHeaderPost - POST /callback-with-header /// CallbackWithHeaderPost - POST /callback-with-header
async fn callback_with_header_post( async fn callback_with_header_post(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
query_params: models::CallbackWithHeaderPostQueryParams, query_params: &models::CallbackWithHeaderPostQueryParams,
) -> Result<CallbackWithHeaderPostResponse, ()>; ) -> Result<CallbackWithHeaderPostResponse, E>;
/// ComplexQueryParamGet - GET /complex-query-param /// ComplexQueryParamGet - GET /complex-query-param
async fn complex_query_param_get( async fn complex_query_param_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
query_params: models::ComplexQueryParamGetQueryParams, query_params: &models::ComplexQueryParamGetQueryParams,
) -> Result<ComplexQueryParamGetResponse, ()>; ) -> Result<ComplexQueryParamGetResponse, E>;
/// EnumInPathPathParamGet - GET /enum_in_path/{path_param} /// EnumInPathPathParamGet - GET /enum_in_path/{path_param}
async fn enum_in_path_path_param_get( async fn enum_in_path_path_param_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
path_params: models::EnumInPathPathParamGetPathParams, path_params: &models::EnumInPathPathParamGetPathParams,
) -> Result<EnumInPathPathParamGetResponse, ()>; ) -> Result<EnumInPathPathParamGetResponse, E>;
/// Test a Form Post. /// Test a Form Post.
/// ///
/// FormTest - POST /form-test /// FormTest - POST /form-test
async fn form_test( async fn form_test(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
body: models::FormTestRequest, body: &models::FormTestRequest,
) -> Result<FormTestResponse, ()>; ) -> Result<FormTestResponse, E>;
/// GetWithBooleanParameter - GET /get-with-bool /// GetWithBooleanParameter - GET /get-with-bool
async fn get_with_boolean_parameter( async fn get_with_boolean_parameter(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
query_params: models::GetWithBooleanParameterQueryParams, query_params: &models::GetWithBooleanParameterQueryParams,
) -> Result<GetWithBooleanParameterResponse, ()>; ) -> Result<GetWithBooleanParameterResponse, E>;
/// JsonComplexQueryParamGet - GET /json-complex-query-param /// JsonComplexQueryParamGet - GET /json-complex-query-param
async fn json_complex_query_param_get( async fn json_complex_query_param_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
query_params: models::JsonComplexQueryParamGetQueryParams, query_params: &models::JsonComplexQueryParamGetQueryParams,
) -> Result<JsonComplexQueryParamGetResponse, ()>; ) -> Result<JsonComplexQueryParamGetResponse, E>;
/// MandatoryRequestHeaderGet - GET /mandatory-request-header /// MandatoryRequestHeaderGet - GET /mandatory-request-header
async fn mandatory_request_header_get( async fn mandatory_request_header_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
header_params: models::MandatoryRequestHeaderGetHeaderParams, header_params: &models::MandatoryRequestHeaderGetHeaderParams,
) -> Result<MandatoryRequestHeaderGetResponse, ()>; ) -> Result<MandatoryRequestHeaderGetResponse, E>;
/// MergePatchJsonGet - GET /merge-patch-json /// MergePatchJsonGet - GET /merge-patch-json
async fn merge_patch_json_get( async fn merge_patch_json_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<MergePatchJsonGetResponse, ()>; ) -> Result<MergePatchJsonGetResponse, E>;
/// Get some stuff.. /// Get some stuff..
/// ///
/// MultigetGet - GET /multiget /// MultigetGet - GET /multiget
async fn multiget_get( async fn multiget_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<MultigetGetResponse, ()>; ) -> Result<MultigetGetResponse, E>;
/// MultipleAuthSchemeGet - GET /multiple_auth_scheme /// MultipleAuthSchemeGet - GET /multiple_auth_scheme
async fn multiple_auth_scheme_get( async fn multiple_auth_scheme_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<MultipleAuthSchemeGetResponse, ()>; ) -> Result<MultipleAuthSchemeGetResponse, E>;
/// MultiplePathParamsWithVeryLongPathToTestFormattingPathParamAPathParamBGet - GET /multiple-path-params-with-very-long-path-to-test-formatting/{path_param_a}/{path_param_b} /// MultiplePathParamsWithVeryLongPathToTestFormattingPathParamAPathParamBGet - GET /multiple-path-params-with-very-long-path-to-test-formatting/{path_param_a}/{path_param_b}
async fn multiple_path_params_with_very_long_path_to_test_formatting_path_param_a_path_param_b_get( async fn multiple_path_params_with_very_long_path_to_test_formatting_path_param_a_path_param_b_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
path_params: models::MultiplePathParamsWithVeryLongPathToTestFormattingPathParamAPathParamBGetPathParams, path_params: &models::MultiplePathParamsWithVeryLongPathToTestFormattingPathParamAPathParamBGetPathParams,
) -> Result<MultiplePathParamsWithVeryLongPathToTestFormattingPathParamAPathParamBGetResponse, ()>; ) -> Result<MultiplePathParamsWithVeryLongPathToTestFormattingPathParamAPathParamBGetResponse, E>;
/// OneOfGet - GET /one-of /// OneOfGet - GET /one-of
async fn one_of_get( async fn one_of_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<OneOfGetResponse, ()>; ) -> Result<OneOfGetResponse, E>;
/// OverrideServerGet - GET /override-server /// OverrideServerGet - GET /override-server
async fn override_server_get( async fn override_server_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<OverrideServerGetResponse, ()>; ) -> Result<OverrideServerGetResponse, E>;
/// Get some stuff with parameters.. /// Get some stuff with parameters..
/// ///
/// ParamgetGet - GET /paramget /// ParamgetGet - GET /paramget
async fn paramget_get( async fn paramget_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
query_params: models::ParamgetGetQueryParams, query_params: &models::ParamgetGetQueryParams,
) -> Result<ParamgetGetResponse, ()>; ) -> Result<ParamgetGetResponse, E>;
/// ReadonlyAuthSchemeGet - GET /readonly_auth_scheme /// ReadonlyAuthSchemeGet - GET /readonly_auth_scheme
async fn readonly_auth_scheme_get( async fn readonly_auth_scheme_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<ReadonlyAuthSchemeGetResponse, ()>; ) -> Result<ReadonlyAuthSchemeGetResponse, E>;
/// RegisterCallbackPost - POST /register-callback /// RegisterCallbackPost - POST /register-callback
async fn register_callback_post( async fn register_callback_post(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
query_params: models::RegisterCallbackPostQueryParams, query_params: &models::RegisterCallbackPostQueryParams,
) -> Result<RegisterCallbackPostResponse, ()>; ) -> Result<RegisterCallbackPostResponse, E>;
/// RequiredOctetStreamPut - PUT /required_octet_stream /// RequiredOctetStreamPut - PUT /required_octet_stream
async fn required_octet_stream_put( async fn required_octet_stream_put(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
body: Bytes, body: &Bytes,
) -> Result<RequiredOctetStreamPutResponse, ()>; ) -> Result<RequiredOctetStreamPutResponse, E>;
/// ResponsesWithHeadersGet - GET /responses_with_headers /// ResponsesWithHeadersGet - GET /responses_with_headers
async fn responses_with_headers_get( async fn responses_with_headers_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<ResponsesWithHeadersGetResponse, ()>; ) -> Result<ResponsesWithHeadersGetResponse, E>;
/// Rfc7807Get - GET /rfc7807 /// Rfc7807Get - GET /rfc7807
async fn rfc7807_get( async fn rfc7807_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<Rfc7807GetResponse, ()>; ) -> Result<Rfc7807GetResponse, E>;
/// TwoFirstLetterHeaders - POST /operation-two-first-letter-headers /// TwoFirstLetterHeaders - POST /operation-two-first-letter-headers
async fn two_first_letter_headers( async fn two_first_letter_headers(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
header_params: models::TwoFirstLetterHeadersHeaderParams, header_params: &models::TwoFirstLetterHeadersHeaderParams,
) -> Result<TwoFirstLetterHeadersResponse, ()>; ) -> Result<TwoFirstLetterHeadersResponse, E>;
/// UntypedPropertyGet - GET /untyped_property /// UntypedPropertyGet - GET /untyped_property
async fn untyped_property_get( async fn untyped_property_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
body: Option<models::ObjectUntypedProps>, body: &Option<models::ObjectUntypedProps>,
) -> Result<UntypedPropertyGetResponse, ()>; ) -> Result<UntypedPropertyGetResponse, E>;
/// UuidGet - GET /uuid /// UuidGet - GET /uuid
async fn uuid_get( async fn uuid_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<UuidGetResponse, ()>; ) -> Result<UuidGetResponse, E>;
/// XmlExtraPost - POST /xml_extra /// XmlExtraPost - POST /xml_extra
async fn xml_extra_post( async fn xml_extra_post(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
body: Bytes, body: &Bytes,
) -> Result<XmlExtraPostResponse, ()>; ) -> Result<XmlExtraPostResponse, E>;
/// XmlOtherPost - POST /xml_other /// XmlOtherPost - POST /xml_other
async fn xml_other_post( async fn xml_other_post(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
body: Bytes, body: &Bytes,
) -> Result<XmlOtherPostResponse, ()>; ) -> Result<XmlOtherPostResponse, E>;
/// XmlOtherPut - PUT /xml_other /// XmlOtherPut - PUT /xml_other
async fn xml_other_put( async fn xml_other_put(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
body: Bytes, body: &Bytes,
) -> Result<XmlOtherPutResponse, ()>; ) -> Result<XmlOtherPutResponse, E>;
/// Post an array. It's important we test apostrophes, so include one here.. /// Post an array. It's important we test apostrophes, so include one here..
/// ///
/// XmlPost - POST /xml /// XmlPost - POST /xml
async fn xml_post( async fn xml_post(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
body: Bytes, body: &Bytes,
) -> Result<XmlPostResponse, ()>; ) -> Result<XmlPostResponse, E>;
/// XmlPut - PUT /xml /// XmlPut - PUT /xml
async fn xml_put( async fn xml_put(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
body: Bytes, body: &Bytes,
) -> Result<XmlPutResponse, ()>; ) -> Result<XmlPutResponse, E>;
} }

View File

@ -18,13 +18,15 @@ pub enum GetRepoInfoResponse {
/// InfoRepo /// InfoRepo
#[async_trait] #[async_trait]
#[allow(clippy::ptr_arg)] #[allow(clippy::ptr_arg)]
pub trait InfoRepo { pub trait InfoRepo<E: std::fmt::Debug + Send + Sync + 'static = ()>:
super::ErrorHandler<E>
{
/// GetRepoInfo - GET /repos/{repoId} /// GetRepoInfo - GET /repos/{repoId}
async fn get_repo_info( async fn get_repo_info(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
path_params: models::GetRepoInfoPathParams, path_params: &models::GetRepoInfoPathParams,
) -> Result<GetRepoInfoResponse, ()>; ) -> Result<GetRepoInfoResponse, E>;
} }

View File

@ -1,3 +1,23 @@
pub mod default; pub mod default;
pub mod info_repo; pub mod info_repo;
pub mod repo; pub mod repo;
// Error handler for unhandled errors.
#[async_trait::async_trait]
pub trait ErrorHandler<E: std::fmt::Debug + Send + Sync + 'static = ()> {
#[allow(unused_variables)]
#[tracing::instrument(skip_all)]
async fn handle_error(
&self,
method: &::http::Method,
host: &axum::extract::Host,
cookies: &axum_extra::extract::CookieJar,
error: E,
) -> Result<axum::response::Response, http::StatusCode> {
tracing::error!("Unhandled error: {:?}", error);
axum::response::Response::builder()
.status(http::StatusCode::INTERNAL_SERVER_ERROR)
.body(axum::body::Body::empty())
.map_err(|_| http::StatusCode::INTERNAL_SERVER_ERROR)
}
}

View File

@ -18,13 +18,13 @@ pub enum CreateRepoResponse {
/// Repo /// Repo
#[async_trait] #[async_trait]
#[allow(clippy::ptr_arg)] #[allow(clippy::ptr_arg)]
pub trait Repo { pub trait Repo<E: std::fmt::Debug + Send + Sync + 'static = ()>: super::ErrorHandler<E> {
/// CreateRepo - POST /repos /// CreateRepo - POST /repos
async fn create_repo( async fn create_repo(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
body: models::ObjectParam, body: &models::ObjectParam,
) -> Result<CreateRepoResponse, ()>; ) -> Result<CreateRepoResponse, E>;
} }

View File

@ -1 +1 @@
7.11.0-SNAPSHOT 7.12.0-SNAPSHOT

View File

@ -40,7 +40,7 @@ tokio = { version = "1", default-features = false, features = [
] } ] }
tracing = { version = "0.1", features = ["attributes"] } tracing = { version = "0.1", features = ["attributes"] }
uuid = { version = "1", features = ["serde"] } uuid = { version = "1", features = ["serde"] }
validator = { version = "0.19", features = ["derive"] } validator = { version = "0.20", features = ["derive"] }
[dev-dependencies] [dev-dependencies]
tracing-subscriber = "0.3" tracing-subscriber = "0.3"

View File

@ -12,7 +12,7 @@ server, you can easily generate a server stub.
To see how to make this your own, look here: [README]((https://openapi-generator.tech)) To see how to make this your own, look here: [README]((https://openapi-generator.tech))
- API version: 0.0.1 - API version: 0.0.1
- Generator version: 7.11.0-SNAPSHOT - Generator version: 7.12.0-SNAPSHOT
@ -43,16 +43,18 @@ struct ServerImpl {
#[allow(unused_variables)] #[allow(unused_variables)]
#[async_trait] #[async_trait]
impl ops-v3::Api for ServerImpl { impl ops_v3::apis::default::Api for ServerImpl {
// API implementation goes here // API implementation goes here
} }
impl ops_v3::apis::ErrorHandler for ServerImpl {}
pub async fn start_server(addr: &str) { pub async fn start_server(addr: &str) {
// initialize tracing // initialize tracing
tracing_subscriber::fmt::init(); tracing_subscriber::fmt::init();
// Init Axum router // Init Axum router
let app = ops-v3::server::new(Arc::new(ServerImpl)); let app = ops_v3::server::new(Arc::new(ServerImpl));
// Add layers to the router // Add layers to the router
let app = app.layer(...); let app = app.layer(...);

View File

@ -306,300 +306,300 @@ pub enum Op9GetResponse {
/// Default /// Default
#[async_trait] #[async_trait]
#[allow(clippy::ptr_arg)] #[allow(clippy::ptr_arg)]
pub trait Default { pub trait Default<E: std::fmt::Debug + Send + Sync + 'static = ()>: super::ErrorHandler<E> {
/// Op10Get - GET /op10 /// Op10Get - GET /op10
async fn op10_get( async fn op10_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<Op10GetResponse, ()>; ) -> Result<Op10GetResponse, E>;
/// Op11Get - GET /op11 /// Op11Get - GET /op11
async fn op11_get( async fn op11_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<Op11GetResponse, ()>; ) -> Result<Op11GetResponse, E>;
/// Op12Get - GET /op12 /// Op12Get - GET /op12
async fn op12_get( async fn op12_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<Op12GetResponse, ()>; ) -> Result<Op12GetResponse, E>;
/// Op13Get - GET /op13 /// Op13Get - GET /op13
async fn op13_get( async fn op13_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<Op13GetResponse, ()>; ) -> Result<Op13GetResponse, E>;
/// Op14Get - GET /op14 /// Op14Get - GET /op14
async fn op14_get( async fn op14_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<Op14GetResponse, ()>; ) -> Result<Op14GetResponse, E>;
/// Op15Get - GET /op15 /// Op15Get - GET /op15
async fn op15_get( async fn op15_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<Op15GetResponse, ()>; ) -> Result<Op15GetResponse, E>;
/// Op16Get - GET /op16 /// Op16Get - GET /op16
async fn op16_get( async fn op16_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<Op16GetResponse, ()>; ) -> Result<Op16GetResponse, E>;
/// Op17Get - GET /op17 /// Op17Get - GET /op17
async fn op17_get( async fn op17_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<Op17GetResponse, ()>; ) -> Result<Op17GetResponse, E>;
/// Op18Get - GET /op18 /// Op18Get - GET /op18
async fn op18_get( async fn op18_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<Op18GetResponse, ()>; ) -> Result<Op18GetResponse, E>;
/// Op19Get - GET /op19 /// Op19Get - GET /op19
async fn op19_get( async fn op19_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<Op19GetResponse, ()>; ) -> Result<Op19GetResponse, E>;
/// Op1Get - GET /op1 /// Op1Get - GET /op1
async fn op1_get( async fn op1_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<Op1GetResponse, ()>; ) -> Result<Op1GetResponse, E>;
/// Op20Get - GET /op20 /// Op20Get - GET /op20
async fn op20_get( async fn op20_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<Op20GetResponse, ()>; ) -> Result<Op20GetResponse, E>;
/// Op21Get - GET /op21 /// Op21Get - GET /op21
async fn op21_get( async fn op21_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<Op21GetResponse, ()>; ) -> Result<Op21GetResponse, E>;
/// Op22Get - GET /op22 /// Op22Get - GET /op22
async fn op22_get( async fn op22_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<Op22GetResponse, ()>; ) -> Result<Op22GetResponse, E>;
/// Op23Get - GET /op23 /// Op23Get - GET /op23
async fn op23_get( async fn op23_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<Op23GetResponse, ()>; ) -> Result<Op23GetResponse, E>;
/// Op24Get - GET /op24 /// Op24Get - GET /op24
async fn op24_get( async fn op24_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<Op24GetResponse, ()>; ) -> Result<Op24GetResponse, E>;
/// Op25Get - GET /op25 /// Op25Get - GET /op25
async fn op25_get( async fn op25_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<Op25GetResponse, ()>; ) -> Result<Op25GetResponse, E>;
/// Op26Get - GET /op26 /// Op26Get - GET /op26
async fn op26_get( async fn op26_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<Op26GetResponse, ()>; ) -> Result<Op26GetResponse, E>;
/// Op27Get - GET /op27 /// Op27Get - GET /op27
async fn op27_get( async fn op27_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<Op27GetResponse, ()>; ) -> Result<Op27GetResponse, E>;
/// Op28Get - GET /op28 /// Op28Get - GET /op28
async fn op28_get( async fn op28_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<Op28GetResponse, ()>; ) -> Result<Op28GetResponse, E>;
/// Op29Get - GET /op29 /// Op29Get - GET /op29
async fn op29_get( async fn op29_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<Op29GetResponse, ()>; ) -> Result<Op29GetResponse, E>;
/// Op2Get - GET /op2 /// Op2Get - GET /op2
async fn op2_get( async fn op2_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<Op2GetResponse, ()>; ) -> Result<Op2GetResponse, E>;
/// Op30Get - GET /op30 /// Op30Get - GET /op30
async fn op30_get( async fn op30_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<Op30GetResponse, ()>; ) -> Result<Op30GetResponse, E>;
/// Op31Get - GET /op31 /// Op31Get - GET /op31
async fn op31_get( async fn op31_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<Op31GetResponse, ()>; ) -> Result<Op31GetResponse, E>;
/// Op32Get - GET /op32 /// Op32Get - GET /op32
async fn op32_get( async fn op32_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<Op32GetResponse, ()>; ) -> Result<Op32GetResponse, E>;
/// Op33Get - GET /op33 /// Op33Get - GET /op33
async fn op33_get( async fn op33_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<Op33GetResponse, ()>; ) -> Result<Op33GetResponse, E>;
/// Op34Get - GET /op34 /// Op34Get - GET /op34
async fn op34_get( async fn op34_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<Op34GetResponse, ()>; ) -> Result<Op34GetResponse, E>;
/// Op35Get - GET /op35 /// Op35Get - GET /op35
async fn op35_get( async fn op35_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<Op35GetResponse, ()>; ) -> Result<Op35GetResponse, E>;
/// Op36Get - GET /op36 /// Op36Get - GET /op36
async fn op36_get( async fn op36_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<Op36GetResponse, ()>; ) -> Result<Op36GetResponse, E>;
/// Op37Get - GET /op37 /// Op37Get - GET /op37
async fn op37_get( async fn op37_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<Op37GetResponse, ()>; ) -> Result<Op37GetResponse, E>;
/// Op3Get - GET /op3 /// Op3Get - GET /op3
async fn op3_get( async fn op3_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<Op3GetResponse, ()>; ) -> Result<Op3GetResponse, E>;
/// Op4Get - GET /op4 /// Op4Get - GET /op4
async fn op4_get( async fn op4_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<Op4GetResponse, ()>; ) -> Result<Op4GetResponse, E>;
/// Op5Get - GET /op5 /// Op5Get - GET /op5
async fn op5_get( async fn op5_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<Op5GetResponse, ()>; ) -> Result<Op5GetResponse, E>;
/// Op6Get - GET /op6 /// Op6Get - GET /op6
async fn op6_get( async fn op6_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<Op6GetResponse, ()>; ) -> Result<Op6GetResponse, E>;
/// Op7Get - GET /op7 /// Op7Get - GET /op7
async fn op7_get( async fn op7_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<Op7GetResponse, ()>; ) -> Result<Op7GetResponse, E>;
/// Op8Get - GET /op8 /// Op8Get - GET /op8
async fn op8_get( async fn op8_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<Op8GetResponse, ()>; ) -> Result<Op8GetResponse, E>;
/// Op9Get - GET /op9 /// Op9Get - GET /op9
async fn op9_get( async fn op9_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<Op9GetResponse, ()>; ) -> Result<Op9GetResponse, E>;
} }

View File

@ -1 +1,21 @@
pub mod default; pub mod default;
// Error handler for unhandled errors.
#[async_trait::async_trait]
pub trait ErrorHandler<E: std::fmt::Debug + Send + Sync + 'static = ()> {
#[allow(unused_variables)]
#[tracing::instrument(skip_all)]
async fn handle_error(
&self,
method: &::http::Method,
host: &axum::extract::Host,
cookies: &axum_extra::extract::CookieJar,
error: E,
) -> Result<axum::response::Response, http::StatusCode> {
tracing::error!("Unhandled error: {:?}", error);
axum::response::Response::builder()
.status(http::StatusCode::INTERNAL_SERVER_ERROR)
.body(axum::body::Body::empty())
.map_err(|_| http::StatusCode::INTERNAL_SERVER_ERROR)
}
}

View File

@ -42,7 +42,7 @@ tokio = { version = "1", default-features = false, features = [
] } ] }
tracing = { version = "0.1", features = ["attributes"] } tracing = { version = "0.1", features = ["attributes"] }
uuid = { version = "1", features = ["serde"] } uuid = { version = "1", features = ["serde"] }
validator = { version = "0.19", features = ["derive"] } validator = { version = "0.20", features = ["derive"] }
[dev-dependencies] [dev-dependencies]
tracing-subscriber = "0.3" tracing-subscriber = "0.3"

View File

@ -12,7 +12,7 @@ server, you can easily generate a server stub.
To see how to make this your own, look here: [README]((https://openapi-generator.tech)) To see how to make this your own, look here: [README]((https://openapi-generator.tech))
- API version: 1.0.0 - API version: 1.0.0
- Generator version: 7.11.0-SNAPSHOT - Generator version: 7.12.0-SNAPSHOT
@ -43,16 +43,18 @@ struct ServerImpl {
#[allow(unused_variables)] #[allow(unused_variables)]
#[async_trait] #[async_trait]
impl petstore-with-fake-endpoints-models-for-testing::Api for ServerImpl { impl petstore_with_fake_endpoints_models_for_testing::apis::default::Api for ServerImpl {
// API implementation goes here // API implementation goes here
} }
impl petstore_with_fake_endpoints_models_for_testing::apis::ErrorHandler for ServerImpl {}
pub async fn start_server(addr: &str) { pub async fn start_server(addr: &str) {
// initialize tracing // initialize tracing
tracing_subscriber::fmt::init(); tracing_subscriber::fmt::init();
// Init Axum router // Init Axum router
let app = petstore-with-fake-endpoints-models-for-testing::server::new(Arc::new(ServerImpl)); let app = petstore_with_fake_endpoints_models_for_testing::server::new(Arc::new(ServerImpl));
// Add layers to the router // Add layers to the router
let app = app.layer(...); let app = app.layer(...);

View File

@ -18,15 +18,17 @@ pub enum TestSpecialTagsResponse {
/// AnotherFake /// AnotherFake
#[async_trait] #[async_trait]
#[allow(clippy::ptr_arg)] #[allow(clippy::ptr_arg)]
pub trait AnotherFake { pub trait AnotherFake<E: std::fmt::Debug + Send + Sync + 'static = ()>:
super::ErrorHandler<E>
{
/// To test special tags. /// To test special tags.
/// ///
/// TestSpecialTags - PATCH /v2/another-fake/dummy /// TestSpecialTags - PATCH /v2/another-fake/dummy
async fn test_special_tags( async fn test_special_tags(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
body: models::Client, body: &models::Client,
) -> Result<TestSpecialTagsResponse, ()>; ) -> Result<TestSpecialTagsResponse, E>;
} }

View File

@ -118,132 +118,132 @@ pub enum TestJsonFormDataResponse {
/// Fake /// Fake
#[async_trait] #[async_trait]
#[allow(clippy::ptr_arg)] #[allow(clippy::ptr_arg)]
pub trait Fake { pub trait Fake<E: std::fmt::Debug + Send + Sync + 'static = ()>: super::ErrorHandler<E> {
/// Call123example - GET /v2/fake/operation-with-numeric-id /// Call123example - GET /v2/fake/operation-with-numeric-id
async fn call123example( async fn call123example(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<Call123exampleResponse, ()>; ) -> Result<Call123exampleResponse, E>;
/// FakeOuterBooleanSerialize - POST /v2/fake/outer/boolean /// FakeOuterBooleanSerialize - POST /v2/fake/outer/boolean
async fn fake_outer_boolean_serialize( async fn fake_outer_boolean_serialize(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
body: Option<models::OuterBoolean>, body: &Option<models::OuterBoolean>,
) -> Result<FakeOuterBooleanSerializeResponse, ()>; ) -> Result<FakeOuterBooleanSerializeResponse, E>;
/// FakeOuterCompositeSerialize - POST /v2/fake/outer/composite /// FakeOuterCompositeSerialize - POST /v2/fake/outer/composite
async fn fake_outer_composite_serialize( async fn fake_outer_composite_serialize(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
body: Option<models::OuterComposite>, body: &Option<models::OuterComposite>,
) -> Result<FakeOuterCompositeSerializeResponse, ()>; ) -> Result<FakeOuterCompositeSerializeResponse, E>;
/// FakeOuterNumberSerialize - POST /v2/fake/outer/number /// FakeOuterNumberSerialize - POST /v2/fake/outer/number
async fn fake_outer_number_serialize( async fn fake_outer_number_serialize(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
body: Option<models::OuterNumber>, body: &Option<models::OuterNumber>,
) -> Result<FakeOuterNumberSerializeResponse, ()>; ) -> Result<FakeOuterNumberSerializeResponse, E>;
/// FakeOuterStringSerialize - POST /v2/fake/outer/string /// FakeOuterStringSerialize - POST /v2/fake/outer/string
async fn fake_outer_string_serialize( async fn fake_outer_string_serialize(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
body: Option<models::OuterString>, body: &Option<models::OuterString>,
) -> Result<FakeOuterStringSerializeResponse, ()>; ) -> Result<FakeOuterStringSerializeResponse, E>;
/// FakeResponseWithNumericalDescription - GET /v2/fake/response-with-numerical-description /// FakeResponseWithNumericalDescription - GET /v2/fake/response-with-numerical-description
async fn fake_response_with_numerical_description( async fn fake_response_with_numerical_description(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<FakeResponseWithNumericalDescriptionResponse, ()>; ) -> Result<FakeResponseWithNumericalDescriptionResponse, E>;
/// HyphenParam - GET /v2/fake/hyphenParam/{hyphen-param} /// HyphenParam - GET /v2/fake/hyphenParam/{hyphen-param}
async fn hyphen_param( async fn hyphen_param(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
path_params: models::HyphenParamPathParams, path_params: &models::HyphenParamPathParams,
) -> Result<HyphenParamResponse, ()>; ) -> Result<HyphenParamResponse, E>;
/// TestBodyWithQueryParams - PUT /v2/fake/body-with-query-params /// TestBodyWithQueryParams - PUT /v2/fake/body-with-query-params
async fn test_body_with_query_params( async fn test_body_with_query_params(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
query_params: models::TestBodyWithQueryParamsQueryParams, query_params: &models::TestBodyWithQueryParamsQueryParams,
body: models::User, body: &models::User,
) -> Result<TestBodyWithQueryParamsResponse, ()>; ) -> Result<TestBodyWithQueryParamsResponse, E>;
/// To test \"client\" model. /// To test \"client\" model.
/// ///
/// TestClientModel - PATCH /v2/fake /// TestClientModel - PATCH /v2/fake
async fn test_client_model( async fn test_client_model(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
body: models::Client, body: &models::Client,
) -> Result<TestClientModelResponse, ()>; ) -> Result<TestClientModelResponse, E>;
/// Fake endpoint for testing various parameters 假端點 偽のエンドポイント 가짜 엔드 포인트. /// Fake endpoint for testing various parameters 假端點 偽のエンドポイント 가짜 엔드 포인트.
/// ///
/// TestEndpointParameters - POST /v2/fake /// TestEndpointParameters - POST /v2/fake
async fn test_endpoint_parameters( async fn test_endpoint_parameters(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
body: models::TestEndpointParametersRequest, body: &models::TestEndpointParametersRequest,
) -> Result<TestEndpointParametersResponse, ()>; ) -> Result<TestEndpointParametersResponse, E>;
/// To test enum parameters. /// To test enum parameters.
/// ///
/// TestEnumParameters - GET /v2/fake /// TestEnumParameters - GET /v2/fake
async fn test_enum_parameters( async fn test_enum_parameters(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
header_params: models::TestEnumParametersHeaderParams, header_params: &models::TestEnumParametersHeaderParams,
query_params: models::TestEnumParametersQueryParams, query_params: &models::TestEnumParametersQueryParams,
body: Option<models::TestEnumParametersRequest>, body: &Option<models::TestEnumParametersRequest>,
) -> Result<TestEnumParametersResponse, ()>; ) -> Result<TestEnumParametersResponse, E>;
/// test inline additionalProperties. /// test inline additionalProperties.
/// ///
/// TestInlineAdditionalProperties - POST /v2/fake/inline-additionalProperties /// TestInlineAdditionalProperties - POST /v2/fake/inline-additionalProperties
async fn test_inline_additional_properties( async fn test_inline_additional_properties(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
body: std::collections::HashMap<String, String>, body: &std::collections::HashMap<String, String>,
) -> Result<TestInlineAdditionalPropertiesResponse, ()>; ) -> Result<TestInlineAdditionalPropertiesResponse, E>;
/// test json serialization of form data. /// test json serialization of form data.
/// ///
/// TestJsonFormData - GET /v2/fake/jsonFormData /// TestJsonFormData - GET /v2/fake/jsonFormData
async fn test_json_form_data( async fn test_json_form_data(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
body: models::TestJsonFormDataRequest, body: &models::TestJsonFormDataRequest,
) -> Result<TestJsonFormDataResponse, ()>; ) -> Result<TestJsonFormDataResponse, E>;
} }

View File

@ -18,15 +18,17 @@ pub enum TestClassnameResponse {
/// FakeClassnameTags123 /// FakeClassnameTags123
#[async_trait] #[async_trait]
#[allow(clippy::ptr_arg)] #[allow(clippy::ptr_arg)]
pub trait FakeClassnameTags123 { pub trait FakeClassnameTags123<E: std::fmt::Debug + Send + Sync + 'static = ()>:
super::ErrorHandler<E>
{
/// To test class name in snake case. /// To test class name in snake case.
/// ///
/// TestClassname - PATCH /v2/fake_classname_test /// TestClassname - PATCH /v2/fake_classname_test
async fn test_classname( async fn test_classname(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
body: models::Client, body: &models::Client,
) -> Result<TestClassnameResponse, ()>; ) -> Result<TestClassnameResponse, E>;
} }

View File

@ -17,3 +17,23 @@ pub trait ApiKeyAuthHeader {
key: &str, key: &str,
) -> Option<Self::Claims>; ) -> Option<Self::Claims>;
} }
// Error handler for unhandled errors.
#[async_trait::async_trait]
pub trait ErrorHandler<E: std::fmt::Debug + Send + Sync + 'static = ()> {
#[allow(unused_variables)]
#[tracing::instrument(skip_all)]
async fn handle_error(
&self,
method: &::http::Method,
host: &axum::extract::Host,
cookies: &axum_extra::extract::CookieJar,
error: E,
) -> Result<axum::response::Response, http::StatusCode> {
tracing::error!("Unhandled error: {:?}", error);
axum::response::Response::builder()
.status(http::StatusCode::INTERNAL_SERVER_ERROR)
.body(axum::body::Body::empty())
.map_err(|_| http::StatusCode::INTERNAL_SERVER_ERROR)
}
}

View File

@ -86,7 +86,7 @@ pub enum UploadFileResponse {
/// Pet /// Pet
#[async_trait] #[async_trait]
#[allow(clippy::ptr_arg)] #[allow(clippy::ptr_arg)]
pub trait Pet { pub trait Pet<E: std::fmt::Debug + Send + Sync + 'static = ()>: super::ErrorHandler<E> {
type Claims; type Claims;
/// Add a new pet to the store. /// Add a new pet to the store.
@ -94,90 +94,90 @@ pub trait Pet {
/// AddPet - POST /v2/pet /// AddPet - POST /v2/pet
async fn add_pet( async fn add_pet(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
body: models::Pet, body: &models::Pet,
) -> Result<AddPetResponse, ()>; ) -> Result<AddPetResponse, E>;
/// Deletes a pet. /// Deletes a pet.
/// ///
/// DeletePet - DELETE /v2/pet/{petId} /// DeletePet - DELETE /v2/pet/{petId}
async fn delete_pet( async fn delete_pet(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
header_params: models::DeletePetHeaderParams, header_params: &models::DeletePetHeaderParams,
path_params: models::DeletePetPathParams, path_params: &models::DeletePetPathParams,
) -> Result<DeletePetResponse, ()>; ) -> Result<DeletePetResponse, E>;
/// Finds Pets by status. /// Finds Pets by status.
/// ///
/// FindPetsByStatus - GET /v2/pet/findByStatus /// FindPetsByStatus - GET /v2/pet/findByStatus
async fn find_pets_by_status( async fn find_pets_by_status(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
query_params: models::FindPetsByStatusQueryParams, query_params: &models::FindPetsByStatusQueryParams,
) -> Result<FindPetsByStatusResponse, ()>; ) -> Result<FindPetsByStatusResponse, E>;
/// Finds Pets by tags. /// Finds Pets by tags.
/// ///
/// FindPetsByTags - GET /v2/pet/findByTags /// FindPetsByTags - GET /v2/pet/findByTags
async fn find_pets_by_tags( async fn find_pets_by_tags(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
query_params: models::FindPetsByTagsQueryParams, query_params: &models::FindPetsByTagsQueryParams,
) -> Result<FindPetsByTagsResponse, ()>; ) -> Result<FindPetsByTagsResponse, E>;
/// Find pet by ID. /// Find pet by ID.
/// ///
/// GetPetById - GET /v2/pet/{petId} /// GetPetById - GET /v2/pet/{petId}
async fn get_pet_by_id( async fn get_pet_by_id(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
claims: Self::Claims, claims: &Self::Claims,
path_params: models::GetPetByIdPathParams, path_params: &models::GetPetByIdPathParams,
) -> Result<GetPetByIdResponse, ()>; ) -> Result<GetPetByIdResponse, E>;
/// Update an existing pet. /// Update an existing pet.
/// ///
/// UpdatePet - PUT /v2/pet /// UpdatePet - PUT /v2/pet
async fn update_pet( async fn update_pet(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
body: models::Pet, body: &models::Pet,
) -> Result<UpdatePetResponse, ()>; ) -> Result<UpdatePetResponse, E>;
/// Updates a pet in the store with form data. /// Updates a pet in the store with form data.
/// ///
/// UpdatePetWithForm - POST /v2/pet/{petId} /// UpdatePetWithForm - POST /v2/pet/{petId}
async fn update_pet_with_form( async fn update_pet_with_form(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
path_params: models::UpdatePetWithFormPathParams, path_params: &models::UpdatePetWithFormPathParams,
body: Option<models::UpdatePetWithFormRequest>, body: &Option<models::UpdatePetWithFormRequest>,
) -> Result<UpdatePetWithFormResponse, ()>; ) -> Result<UpdatePetWithFormResponse, E>;
/// uploads an image. /// uploads an image.
/// ///
/// UploadFile - POST /v2/pet/{petId}/uploadImage /// UploadFile - POST /v2/pet/{petId}/uploadImage
async fn upload_file( async fn upload_file(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
path_params: models::UploadFilePathParams, path_params: &models::UploadFilePathParams,
body: Multipart, body: &Multipart,
) -> Result<UploadFileResponse, ()>; ) -> Result<UploadFileResponse, E>;
} }

View File

@ -50,7 +50,7 @@ pub enum PlaceOrderResponse {
/// Store /// Store
#[async_trait] #[async_trait]
#[allow(clippy::ptr_arg)] #[allow(clippy::ptr_arg)]
pub trait Store { pub trait Store<E: std::fmt::Debug + Send + Sync + 'static = ()>: super::ErrorHandler<E> {
type Claims; type Claims;
/// Delete purchase order by ID. /// Delete purchase order by ID.
@ -58,42 +58,42 @@ pub trait Store {
/// DeleteOrder - DELETE /v2/store/order/{order_id} /// DeleteOrder - DELETE /v2/store/order/{order_id}
async fn delete_order( async fn delete_order(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
path_params: models::DeleteOrderPathParams, path_params: &models::DeleteOrderPathParams,
) -> Result<DeleteOrderResponse, ()>; ) -> Result<DeleteOrderResponse, E>;
/// Returns pet inventories by status. /// Returns pet inventories by status.
/// ///
/// GetInventory - GET /v2/store/inventory /// GetInventory - GET /v2/store/inventory
async fn get_inventory( async fn get_inventory(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
claims: Self::Claims, claims: &Self::Claims,
) -> Result<GetInventoryResponse, ()>; ) -> Result<GetInventoryResponse, E>;
/// Find purchase order by ID. /// Find purchase order by ID.
/// ///
/// GetOrderById - GET /v2/store/order/{order_id} /// GetOrderById - GET /v2/store/order/{order_id}
async fn get_order_by_id( async fn get_order_by_id(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
path_params: models::GetOrderByIdPathParams, path_params: &models::GetOrderByIdPathParams,
) -> Result<GetOrderByIdResponse, ()>; ) -> Result<GetOrderByIdResponse, E>;
/// Place an order for a pet. /// Place an order for a pet.
/// ///
/// PlaceOrder - POST /v2/store/order /// PlaceOrder - POST /v2/store/order
async fn place_order( async fn place_order(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
body: models::Order, body: &models::Order,
) -> Result<PlaceOrderResponse, ()>; ) -> Result<PlaceOrderResponse, E>;
} }

View File

@ -88,92 +88,92 @@ pub enum UpdateUserResponse {
/// User /// User
#[async_trait] #[async_trait]
#[allow(clippy::ptr_arg)] #[allow(clippy::ptr_arg)]
pub trait User { pub trait User<E: std::fmt::Debug + Send + Sync + 'static = ()>: super::ErrorHandler<E> {
/// Create user. /// Create user.
/// ///
/// CreateUser - POST /v2/user /// CreateUser - POST /v2/user
async fn create_user( async fn create_user(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
body: models::User, body: &models::User,
) -> Result<CreateUserResponse, ()>; ) -> Result<CreateUserResponse, E>;
/// Creates list of users with given input array. /// Creates list of users with given input array.
/// ///
/// CreateUsersWithArrayInput - POST /v2/user/createWithArray /// CreateUsersWithArrayInput - POST /v2/user/createWithArray
async fn create_users_with_array_input( async fn create_users_with_array_input(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
body: Vec<models::User>, body: &Vec<models::User>,
) -> Result<CreateUsersWithArrayInputResponse, ()>; ) -> Result<CreateUsersWithArrayInputResponse, E>;
/// Creates list of users with given input array. /// Creates list of users with given input array.
/// ///
/// CreateUsersWithListInput - POST /v2/user/createWithList /// CreateUsersWithListInput - POST /v2/user/createWithList
async fn create_users_with_list_input( async fn create_users_with_list_input(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
body: Vec<models::User>, body: &Vec<models::User>,
) -> Result<CreateUsersWithListInputResponse, ()>; ) -> Result<CreateUsersWithListInputResponse, E>;
/// Delete user. /// Delete user.
/// ///
/// DeleteUser - DELETE /v2/user/{username} /// DeleteUser - DELETE /v2/user/{username}
async fn delete_user( async fn delete_user(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
path_params: models::DeleteUserPathParams, path_params: &models::DeleteUserPathParams,
) -> Result<DeleteUserResponse, ()>; ) -> Result<DeleteUserResponse, E>;
/// Get user by user name. /// Get user by user name.
/// ///
/// GetUserByName - GET /v2/user/{username} /// GetUserByName - GET /v2/user/{username}
async fn get_user_by_name( async fn get_user_by_name(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
path_params: models::GetUserByNamePathParams, path_params: &models::GetUserByNamePathParams,
) -> Result<GetUserByNameResponse, ()>; ) -> Result<GetUserByNameResponse, E>;
/// Logs user into the system. /// Logs user into the system.
/// ///
/// LoginUser - GET /v2/user/login /// LoginUser - GET /v2/user/login
async fn login_user( async fn login_user(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
query_params: models::LoginUserQueryParams, query_params: &models::LoginUserQueryParams,
) -> Result<LoginUserResponse, ()>; ) -> Result<LoginUserResponse, E>;
/// Logs out current logged in user session. /// Logs out current logged in user session.
/// ///
/// LogoutUser - GET /v2/user/logout /// LogoutUser - GET /v2/user/logout
async fn logout_user( async fn logout_user(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<LogoutUserResponse, ()>; ) -> Result<LogoutUserResponse, E>;
/// Updated user. /// Updated user.
/// ///
/// UpdateUser - PUT /v2/user/{username} /// UpdateUser - PUT /v2/user/{username}
async fn update_user( async fn update_user(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
path_params: models::UpdateUserPathParams, path_params: &models::UpdateUserPathParams,
body: models::User, body: &models::User,
) -> Result<UpdateUserResponse, ()>; ) -> Result<UpdateUserResponse, E>;
} }

View File

@ -1 +1 @@
7.11.0-SNAPSHOT 7.12.0-SNAPSHOT

View File

@ -41,7 +41,7 @@ tokio = { version = "1", default-features = false, features = [
] } ] }
tracing = { version = "0.1", features = ["attributes"] } tracing = { version = "0.1", features = ["attributes"] }
uuid = { version = "1", features = ["serde"] } uuid = { version = "1", features = ["serde"] }
validator = { version = "0.19", features = ["derive"] } validator = { version = "0.20", features = ["derive"] }
[dev-dependencies] [dev-dependencies]
tracing-subscriber = "0.3" tracing-subscriber = "0.3"

View File

@ -12,7 +12,7 @@ server, you can easily generate a server stub.
To see how to make this your own, look here: [README]((https://openapi-generator.tech)) To see how to make this your own, look here: [README]((https://openapi-generator.tech))
- API version: 1.0.0 - API version: 1.0.0
- Generator version: 7.11.0-SNAPSHOT - Generator version: 7.12.0-SNAPSHOT
@ -43,10 +43,12 @@ struct ServerImpl {
#[allow(unused_variables)] #[allow(unused_variables)]
#[async_trait] #[async_trait]
impl petstore::Api for ServerImpl { impl petstore::apis::default::Api for ServerImpl {
// API implementation goes here // API implementation goes here
} }
impl petstore::apis::ErrorHandler for ServerImpl {}
pub async fn start_server(addr: &str) { pub async fn start_server(addr: &str) {
// initialize tracing // initialize tracing
tracing_subscriber::fmt::init(); tracing_subscriber::fmt::init();

View File

@ -14,3 +14,23 @@ pub trait ApiKeyAuthHeader {
key: &str, key: &str,
) -> Option<Self::Claims>; ) -> Option<Self::Claims>;
} }
// Error handler for unhandled errors.
#[async_trait::async_trait]
pub trait ErrorHandler<E: std::fmt::Debug + Send + Sync + 'static = ()> {
#[allow(unused_variables)]
#[tracing::instrument(skip_all)]
async fn handle_error(
&self,
method: &::http::Method,
host: &axum::extract::Host,
cookies: &axum_extra::extract::CookieJar,
error: E,
) -> Result<axum::response::Response, http::StatusCode> {
tracing::error!("Unhandled error: {:?}", error);
axum::response::Response::builder()
.status(http::StatusCode::INTERNAL_SERVER_ERROR)
.body(axum::body::Body::empty())
.map_err(|_| http::StatusCode::INTERNAL_SERVER_ERROR)
}
}

View File

@ -90,7 +90,7 @@ pub enum UploadFileResponse {
/// Pet /// Pet
#[async_trait] #[async_trait]
#[allow(clippy::ptr_arg)] #[allow(clippy::ptr_arg)]
pub trait Pet { pub trait Pet<E: std::fmt::Debug + Send + Sync + 'static = ()>: super::ErrorHandler<E> {
type Claims; type Claims;
/// Add a new pet to the store. /// Add a new pet to the store.
@ -98,90 +98,90 @@ pub trait Pet {
/// AddPet - POST /v2/pet /// AddPet - POST /v2/pet
async fn add_pet( async fn add_pet(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
body: models::Pet, body: &models::Pet,
) -> Result<AddPetResponse, ()>; ) -> Result<AddPetResponse, E>;
/// Deletes a pet. /// Deletes a pet.
/// ///
/// DeletePet - DELETE /v2/pet/{petId} /// DeletePet - DELETE /v2/pet/{petId}
async fn delete_pet( async fn delete_pet(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
header_params: models::DeletePetHeaderParams, header_params: &models::DeletePetHeaderParams,
path_params: models::DeletePetPathParams, path_params: &models::DeletePetPathParams,
) -> Result<DeletePetResponse, ()>; ) -> Result<DeletePetResponse, E>;
/// Finds Pets by status. /// Finds Pets by status.
/// ///
/// FindPetsByStatus - GET /v2/pet/findByStatus /// FindPetsByStatus - GET /v2/pet/findByStatus
async fn find_pets_by_status( async fn find_pets_by_status(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
query_params: models::FindPetsByStatusQueryParams, query_params: &models::FindPetsByStatusQueryParams,
) -> Result<FindPetsByStatusResponse, ()>; ) -> Result<FindPetsByStatusResponse, E>;
/// Finds Pets by tags. /// Finds Pets by tags.
/// ///
/// FindPetsByTags - GET /v2/pet/findByTags /// FindPetsByTags - GET /v2/pet/findByTags
async fn find_pets_by_tags( async fn find_pets_by_tags(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
query_params: models::FindPetsByTagsQueryParams, query_params: &models::FindPetsByTagsQueryParams,
) -> Result<FindPetsByTagsResponse, ()>; ) -> Result<FindPetsByTagsResponse, E>;
/// Find pet by ID. /// Find pet by ID.
/// ///
/// GetPetById - GET /v2/pet/{petId} /// GetPetById - GET /v2/pet/{petId}
async fn get_pet_by_id( async fn get_pet_by_id(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
claims: Self::Claims, claims: &Self::Claims,
path_params: models::GetPetByIdPathParams, path_params: &models::GetPetByIdPathParams,
) -> Result<GetPetByIdResponse, ()>; ) -> Result<GetPetByIdResponse, E>;
/// Update an existing pet. /// Update an existing pet.
/// ///
/// UpdatePet - PUT /v2/pet /// UpdatePet - PUT /v2/pet
async fn update_pet( async fn update_pet(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
body: models::Pet, body: &models::Pet,
) -> Result<UpdatePetResponse, ()>; ) -> Result<UpdatePetResponse, E>;
/// Updates a pet in the store with form data. /// Updates a pet in the store with form data.
/// ///
/// UpdatePetWithForm - POST /v2/pet/{petId} /// UpdatePetWithForm - POST /v2/pet/{petId}
async fn update_pet_with_form( async fn update_pet_with_form(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
path_params: models::UpdatePetWithFormPathParams, path_params: &models::UpdatePetWithFormPathParams,
body: Option<models::UpdatePetWithFormRequest>, body: &Option<models::UpdatePetWithFormRequest>,
) -> Result<UpdatePetWithFormResponse, ()>; ) -> Result<UpdatePetWithFormResponse, E>;
/// uploads an image. /// uploads an image.
/// ///
/// UploadFile - POST /v2/pet/{petId}/uploadImage /// UploadFile - POST /v2/pet/{petId}/uploadImage
async fn upload_file( async fn upload_file(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
path_params: models::UploadFilePathParams, path_params: &models::UploadFilePathParams,
body: Multipart, body: &Multipart,
) -> Result<UploadFileResponse, ()>; ) -> Result<UploadFileResponse, E>;
} }

View File

@ -50,7 +50,7 @@ pub enum PlaceOrderResponse {
/// Store /// Store
#[async_trait] #[async_trait]
#[allow(clippy::ptr_arg)] #[allow(clippy::ptr_arg)]
pub trait Store { pub trait Store<E: std::fmt::Debug + Send + Sync + 'static = ()>: super::ErrorHandler<E> {
type Claims; type Claims;
/// Delete purchase order by ID. /// Delete purchase order by ID.
@ -58,42 +58,42 @@ pub trait Store {
/// DeleteOrder - DELETE /v2/store/order/{orderId} /// DeleteOrder - DELETE /v2/store/order/{orderId}
async fn delete_order( async fn delete_order(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
path_params: models::DeleteOrderPathParams, path_params: &models::DeleteOrderPathParams,
) -> Result<DeleteOrderResponse, ()>; ) -> Result<DeleteOrderResponse, E>;
/// Returns pet inventories by status. /// Returns pet inventories by status.
/// ///
/// GetInventory - GET /v2/store/inventory /// GetInventory - GET /v2/store/inventory
async fn get_inventory( async fn get_inventory(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
claims: Self::Claims, claims: &Self::Claims,
) -> Result<GetInventoryResponse, ()>; ) -> Result<GetInventoryResponse, E>;
/// Find purchase order by ID. /// Find purchase order by ID.
/// ///
/// GetOrderById - GET /v2/store/order/{orderId} /// GetOrderById - GET /v2/store/order/{orderId}
async fn get_order_by_id( async fn get_order_by_id(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
path_params: models::GetOrderByIdPathParams, path_params: &models::GetOrderByIdPathParams,
) -> Result<GetOrderByIdResponse, ()>; ) -> Result<GetOrderByIdResponse, E>;
/// Place an order for a pet. /// Place an order for a pet.
/// ///
/// PlaceOrder - POST /v2/store/order /// PlaceOrder - POST /v2/store/order
async fn place_order( async fn place_order(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
body: models::Order, body: &models::Order,
) -> Result<PlaceOrderResponse, ()>; ) -> Result<PlaceOrderResponse, E>;
} }

View File

@ -89,7 +89,7 @@ pub enum UpdateUserResponse {
/// User /// User
#[async_trait] #[async_trait]
#[allow(clippy::ptr_arg)] #[allow(clippy::ptr_arg)]
pub trait User { pub trait User<E: std::fmt::Debug + Send + Sync + 'static = ()>: super::ErrorHandler<E> {
type Claims; type Claims;
/// Create user. /// Create user.
@ -97,92 +97,92 @@ pub trait User {
/// CreateUser - POST /v2/user /// CreateUser - POST /v2/user
async fn create_user( async fn create_user(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
claims: Self::Claims, claims: &Self::Claims,
body: models::User, body: &models::User,
) -> Result<CreateUserResponse, ()>; ) -> Result<CreateUserResponse, E>;
/// Creates list of users with given input array. /// Creates list of users with given input array.
/// ///
/// CreateUsersWithArrayInput - POST /v2/user/createWithArray /// CreateUsersWithArrayInput - POST /v2/user/createWithArray
async fn create_users_with_array_input( async fn create_users_with_array_input(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
claims: Self::Claims, claims: &Self::Claims,
body: Vec<models::User>, body: &Vec<models::User>,
) -> Result<CreateUsersWithArrayInputResponse, ()>; ) -> Result<CreateUsersWithArrayInputResponse, E>;
/// Creates list of users with given input array. /// Creates list of users with given input array.
/// ///
/// CreateUsersWithListInput - POST /v2/user/createWithList /// CreateUsersWithListInput - POST /v2/user/createWithList
async fn create_users_with_list_input( async fn create_users_with_list_input(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
claims: Self::Claims, claims: &Self::Claims,
body: Vec<models::User>, body: &Vec<models::User>,
) -> Result<CreateUsersWithListInputResponse, ()>; ) -> Result<CreateUsersWithListInputResponse, E>;
/// Delete user. /// Delete user.
/// ///
/// DeleteUser - DELETE /v2/user/{username} /// DeleteUser - DELETE /v2/user/{username}
async fn delete_user( async fn delete_user(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
claims: Self::Claims, claims: &Self::Claims,
path_params: models::DeleteUserPathParams, path_params: &models::DeleteUserPathParams,
) -> Result<DeleteUserResponse, ()>; ) -> Result<DeleteUserResponse, E>;
/// Get user by user name. /// Get user by user name.
/// ///
/// GetUserByName - GET /v2/user/{username} /// GetUserByName - GET /v2/user/{username}
async fn get_user_by_name( async fn get_user_by_name(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
path_params: models::GetUserByNamePathParams, path_params: &models::GetUserByNamePathParams,
) -> Result<GetUserByNameResponse, ()>; ) -> Result<GetUserByNameResponse, E>;
/// Logs user into the system. /// Logs user into the system.
/// ///
/// LoginUser - GET /v2/user/login /// LoginUser - GET /v2/user/login
async fn login_user( async fn login_user(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
query_params: models::LoginUserQueryParams, query_params: &models::LoginUserQueryParams,
) -> Result<LoginUserResponse, ()>; ) -> Result<LoginUserResponse, E>;
/// Logs out current logged in user session. /// Logs out current logged in user session.
/// ///
/// LogoutUser - GET /v2/user/logout /// LogoutUser - GET /v2/user/logout
async fn logout_user( async fn logout_user(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
claims: Self::Claims, claims: &Self::Claims,
) -> Result<LogoutUserResponse, ()>; ) -> Result<LogoutUserResponse, E>;
/// Updated user. /// Updated user.
/// ///
/// UpdateUser - PUT /v2/user/{username} /// UpdateUser - PUT /v2/user/{username}
async fn update_user( async fn update_user(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
claims: Self::Claims, claims: &Self::Claims,
path_params: models::UpdateUserPathParams, path_params: &models::UpdateUserPathParams,
body: models::User, body: &models::User,
) -> Result<UpdateUserResponse, ()>; ) -> Result<UpdateUserResponse, E>;
} }

View File

@ -13,54 +13,63 @@ use crate::{header, types::*};
use crate::{apis, models}; use crate::{apis, models};
/// Setup API Server. /// Setup API Server.
pub fn new<I, A, C>(api_impl: I) -> Router pub fn new<I, A, E, C>(api_impl: I) -> Router
where where
I: AsRef<A> + Clone + Send + Sync + 'static, I: AsRef<A> + Clone + Send + Sync + 'static,
A: apis::pet::Pet<Claims = C> A: apis::pet::Pet<E, Claims = C>
+ apis::store::Store<Claims = C> + apis::store::Store<E, Claims = C>
+ apis::user::User<Claims = C> + apis::user::User<E, Claims = C>
+ apis::ApiKeyAuthHeader<Claims = C> + apis::ApiKeyAuthHeader<Claims = C>
+ Send
+ Sync
+ 'static, + 'static,
E: std::fmt::Debug + Send + Sync + 'static,
C: Send + Sync + 'static, C: Send + Sync + 'static,
{ {
// build our application with a route // build our application with a route
Router::new() Router::new()
.route( .route(
"/v2/pet", "/v2/pet",
post(add_pet::<I, A, C>).put(update_pet::<I, A, C>), post(add_pet::<I, A, E, C>).put(update_pet::<I, A, E, C>),
) )
.route( .route(
"/v2/pet/:pet_id", "/v2/pet/:pet_id",
delete(delete_pet::<I, A, C>) delete(delete_pet::<I, A, E, C>)
.get(get_pet_by_id::<I, A, C>) .get(get_pet_by_id::<I, A, E, C>)
.post(update_pet_with_form::<I, A, C>), .post(update_pet_with_form::<I, A, E, C>),
) )
.route("/v2/pet/:pet_id/uploadImage", post(upload_file::<I, A, C>)) .route(
.route("/v2/pet/findByStatus", get(find_pets_by_status::<I, A, C>)) "/v2/pet/:pet_id/uploadImage",
.route("/v2/pet/findByTags", get(find_pets_by_tags::<I, A, C>)) post(upload_file::<I, A, E, C>),
.route("/v2/store/inventory", get(get_inventory::<I, A, C>)) )
.route("/v2/store/order", post(place_order::<I, A, C>)) .route(
"/v2/pet/findByStatus",
get(find_pets_by_status::<I, A, E, C>),
)
.route("/v2/pet/findByTags", get(find_pets_by_tags::<I, A, E, C>))
.route("/v2/store/inventory", get(get_inventory::<I, A, E, C>))
.route("/v2/store/order", post(place_order::<I, A, E, C>))
.route( .route(
"/v2/store/order/:order_id", "/v2/store/order/:order_id",
delete(delete_order::<I, A, C>).get(get_order_by_id::<I, A, C>), delete(delete_order::<I, A, E, C>).get(get_order_by_id::<I, A, E, C>),
) )
.route("/v2/user", post(create_user::<I, A, C>)) .route("/v2/user", post(create_user::<I, A, E, C>))
.route( .route(
"/v2/user/:username", "/v2/user/:username",
delete(delete_user::<I, A, C>) delete(delete_user::<I, A, E, C>)
.get(get_user_by_name::<I, A, C>) .get(get_user_by_name::<I, A, E, C>)
.put(update_user::<I, A, C>), .put(update_user::<I, A, E, C>),
) )
.route( .route(
"/v2/user/createWithArray", "/v2/user/createWithArray",
post(create_users_with_array_input::<I, A, C>), post(create_users_with_array_input::<I, A, E, C>),
) )
.route( .route(
"/v2/user/createWithList", "/v2/user/createWithList",
post(create_users_with_list_input::<I, A, C>), post(create_users_with_list_input::<I, A, E, C>),
) )
.route("/v2/user/login", get(login_user::<I, A, C>)) .route("/v2/user/login", get(login_user::<I, A, E, C>))
.route("/v2/user/logout", get(logout_user::<I, A, C>)) .route("/v2/user/logout", get(logout_user::<I, A, E, C>))
.with_state(api_impl) .with_state(api_impl)
} }
@ -80,7 +89,7 @@ fn add_pet_validation(body: models::Pet) -> std::result::Result<(models::Pet,),
} }
/// AddPet - POST /v2/pet /// AddPet - POST /v2/pet
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
async fn add_pet<I, A, C>( async fn add_pet<I, A, E, C>(
method: Method, method: Method,
host: Host, host: Host,
cookies: CookieJar, cookies: CookieJar,
@ -89,7 +98,8 @@ async fn add_pet<I, A, C>(
) -> Result<Response, StatusCode> ) -> Result<Response, StatusCode>
where where
I: AsRef<A> + Send + Sync, I: AsRef<A> + Send + Sync,
A: apis::pet::Pet<Claims = C>, A: apis::pet::Pet<E, Claims = C> + Send + Sync,
E: std::fmt::Debug + Send + Sync + 'static,
{ {
#[allow(clippy::redundant_closure)] #[allow(clippy::redundant_closure)]
let validation = tokio::task::spawn_blocking(move || add_pet_validation(body)) let validation = tokio::task::spawn_blocking(move || add_pet_validation(body))
@ -103,7 +113,10 @@ where
.map_err(|_| StatusCode::BAD_REQUEST); .map_err(|_| StatusCode::BAD_REQUEST);
}; };
let result = api_impl.as_ref().add_pet(method, host, cookies, body).await; let result = api_impl
.as_ref()
.add_pet(&method, &host, &cookies, &body)
.await;
let mut response = Response::builder(); let mut response = Response::builder();
@ -130,10 +143,14 @@ where
response.body(Body::empty()) response.body(Body::empty())
} }
}, },
Err(_) => { Err(why) => {
// Application code returned an error. This should not happen, as the implementation should // Application code returned an error. This should not happen, as the implementation should
// return a valid response. // return a valid response.
response.status(500).body(Body::empty())
return api_impl
.as_ref()
.handle_error(&method, &host, &cookies, why)
.await;
} }
}; };
@ -158,7 +175,7 @@ fn delete_pet_validation(
} }
/// DeletePet - DELETE /v2/pet/{petId} /// DeletePet - DELETE /v2/pet/{petId}
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
async fn delete_pet<I, A, C>( async fn delete_pet<I, A, E, C>(
method: Method, method: Method,
host: Host, host: Host,
cookies: CookieJar, cookies: CookieJar,
@ -168,7 +185,8 @@ async fn delete_pet<I, A, C>(
) -> Result<Response, StatusCode> ) -> Result<Response, StatusCode>
where where
I: AsRef<A> + Send + Sync, I: AsRef<A> + Send + Sync,
A: apis::pet::Pet<Claims = C>, A: apis::pet::Pet<E, Claims = C> + Send + Sync,
E: std::fmt::Debug + Send + Sync + 'static,
{ {
// Header parameters // Header parameters
let header_params = { let header_params = {
@ -210,7 +228,7 @@ where
let result = api_impl let result = api_impl
.as_ref() .as_ref()
.delete_pet(method, host, cookies, header_params, path_params) .delete_pet(&method, &host, &cookies, &header_params, &path_params)
.await; .await;
let mut response = Response::builder(); let mut response = Response::builder();
@ -222,10 +240,14 @@ where
response.body(Body::empty()) response.body(Body::empty())
} }
}, },
Err(_) => { Err(why) => {
// Application code returned an error. This should not happen, as the implementation should // Application code returned an error. This should not happen, as the implementation should
// return a valid response. // return a valid response.
response.status(500).body(Body::empty())
return api_impl
.as_ref()
.handle_error(&method, &host, &cookies, why)
.await;
} }
}; };
@ -245,7 +267,7 @@ fn find_pets_by_status_validation(
} }
/// FindPetsByStatus - GET /v2/pet/findByStatus /// FindPetsByStatus - GET /v2/pet/findByStatus
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
async fn find_pets_by_status<I, A, C>( async fn find_pets_by_status<I, A, E, C>(
method: Method, method: Method,
host: Host, host: Host,
cookies: CookieJar, cookies: CookieJar,
@ -254,7 +276,8 @@ async fn find_pets_by_status<I, A, C>(
) -> Result<Response, StatusCode> ) -> Result<Response, StatusCode>
where where
I: AsRef<A> + Send + Sync, I: AsRef<A> + Send + Sync,
A: apis::pet::Pet<Claims = C>, A: apis::pet::Pet<E, Claims = C> + Send + Sync,
E: std::fmt::Debug + Send + Sync + 'static,
{ {
#[allow(clippy::redundant_closure)] #[allow(clippy::redundant_closure)]
let validation = let validation =
@ -271,7 +294,7 @@ where
let result = api_impl let result = api_impl
.as_ref() .as_ref()
.find_pets_by_status(method, host, cookies, query_params) .find_pets_by_status(&method, &host, &cookies, &query_params)
.await; .await;
let mut response = Response::builder(); let mut response = Response::builder();
@ -299,10 +322,14 @@ where
response.body(Body::empty()) response.body(Body::empty())
} }
}, },
Err(_) => { Err(why) => {
// Application code returned an error. This should not happen, as the implementation should // Application code returned an error. This should not happen, as the implementation should
// return a valid response. // return a valid response.
response.status(500).body(Body::empty())
return api_impl
.as_ref()
.handle_error(&method, &host, &cookies, why)
.await;
} }
}; };
@ -322,7 +349,7 @@ fn find_pets_by_tags_validation(
} }
/// FindPetsByTags - GET /v2/pet/findByTags /// FindPetsByTags - GET /v2/pet/findByTags
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
async fn find_pets_by_tags<I, A, C>( async fn find_pets_by_tags<I, A, E, C>(
method: Method, method: Method,
host: Host, host: Host,
cookies: CookieJar, cookies: CookieJar,
@ -331,7 +358,8 @@ async fn find_pets_by_tags<I, A, C>(
) -> Result<Response, StatusCode> ) -> Result<Response, StatusCode>
where where
I: AsRef<A> + Send + Sync, I: AsRef<A> + Send + Sync,
A: apis::pet::Pet<Claims = C>, A: apis::pet::Pet<E, Claims = C> + Send + Sync,
E: std::fmt::Debug + Send + Sync + 'static,
{ {
#[allow(clippy::redundant_closure)] #[allow(clippy::redundant_closure)]
let validation = let validation =
@ -348,7 +376,7 @@ where
let result = api_impl let result = api_impl
.as_ref() .as_ref()
.find_pets_by_tags(method, host, cookies, query_params) .find_pets_by_tags(&method, &host, &cookies, &query_params)
.await; .await;
let mut response = Response::builder(); let mut response = Response::builder();
@ -376,10 +404,14 @@ where
response.body(Body::empty()) response.body(Body::empty())
} }
}, },
Err(_) => { Err(why) => {
// Application code returned an error. This should not happen, as the implementation should // Application code returned an error. This should not happen, as the implementation should
// return a valid response. // return a valid response.
response.status(500).body(Body::empty())
return api_impl
.as_ref()
.handle_error(&method, &host, &cookies, why)
.await;
} }
}; };
@ -399,7 +431,7 @@ fn get_pet_by_id_validation(
} }
/// GetPetById - GET /v2/pet/{petId} /// GetPetById - GET /v2/pet/{petId}
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
async fn get_pet_by_id<I, A, C>( async fn get_pet_by_id<I, A, E, C>(
method: Method, method: Method,
host: Host, host: Host,
cookies: CookieJar, cookies: CookieJar,
@ -409,7 +441,8 @@ async fn get_pet_by_id<I, A, C>(
) -> Result<Response, StatusCode> ) -> Result<Response, StatusCode>
where where
I: AsRef<A> + Send + Sync, I: AsRef<A> + Send + Sync,
A: apis::pet::Pet<Claims = C> + apis::ApiKeyAuthHeader<Claims = C>, A: apis::pet::Pet<E, Claims = C> + apis::ApiKeyAuthHeader<Claims = C> + Send + Sync,
E: std::fmt::Debug + Send + Sync + 'static,
{ {
// Authentication // Authentication
let claims_in_header = api_impl let claims_in_header = api_impl
@ -438,7 +471,7 @@ where
let result = api_impl let result = api_impl
.as_ref() .as_ref()
.get_pet_by_id(method, host, cookies, claims, path_params) .get_pet_by_id(&method, &host, &cookies, &claims, &path_params)
.await; .await;
let mut response = Response::builder(); let mut response = Response::builder();
@ -470,10 +503,14 @@ where
response.body(Body::empty()) response.body(Body::empty())
} }
}, },
Err(_) => { Err(why) => {
// Application code returned an error. This should not happen, as the implementation should // Application code returned an error. This should not happen, as the implementation should
// return a valid response. // return a valid response.
response.status(500).body(Body::empty())
return api_impl
.as_ref()
.handle_error(&method, &host, &cookies, why)
.await;
} }
}; };
@ -501,7 +538,7 @@ fn update_pet_validation(
} }
/// UpdatePet - PUT /v2/pet /// UpdatePet - PUT /v2/pet
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
async fn update_pet<I, A, C>( async fn update_pet<I, A, E, C>(
method: Method, method: Method,
host: Host, host: Host,
cookies: CookieJar, cookies: CookieJar,
@ -510,7 +547,8 @@ async fn update_pet<I, A, C>(
) -> Result<Response, StatusCode> ) -> Result<Response, StatusCode>
where where
I: AsRef<A> + Send + Sync, I: AsRef<A> + Send + Sync,
A: apis::pet::Pet<Claims = C>, A: apis::pet::Pet<E, Claims = C> + Send + Sync,
E: std::fmt::Debug + Send + Sync + 'static,
{ {
#[allow(clippy::redundant_closure)] #[allow(clippy::redundant_closure)]
let validation = tokio::task::spawn_blocking(move || update_pet_validation(body)) let validation = tokio::task::spawn_blocking(move || update_pet_validation(body))
@ -526,7 +564,7 @@ where
let result = api_impl let result = api_impl
.as_ref() .as_ref()
.update_pet(method, host, cookies, body) .update_pet(&method, &host, &cookies, &body)
.await; .await;
let mut response = Response::builder(); let mut response = Response::builder();
@ -562,10 +600,14 @@ where
response.body(Body::empty()) response.body(Body::empty())
} }
}, },
Err(_) => { Err(why) => {
// Application code returned an error. This should not happen, as the implementation should // Application code returned an error. This should not happen, as the implementation should
// return a valid response. // return a valid response.
response.status(500).body(Body::empty())
return api_impl
.as_ref()
.handle_error(&method, &host, &cookies, why)
.await;
} }
}; };
@ -603,7 +645,7 @@ fn update_pet_with_form_validation(
} }
/// UpdatePetWithForm - POST /v2/pet/{petId} /// UpdatePetWithForm - POST /v2/pet/{petId}
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
async fn update_pet_with_form<I, A, C>( async fn update_pet_with_form<I, A, E, C>(
method: Method, method: Method,
host: Host, host: Host,
cookies: CookieJar, cookies: CookieJar,
@ -613,7 +655,8 @@ async fn update_pet_with_form<I, A, C>(
) -> Result<Response, StatusCode> ) -> Result<Response, StatusCode>
where where
I: AsRef<A> + Send + Sync, I: AsRef<A> + Send + Sync,
A: apis::pet::Pet<Claims = C>, A: apis::pet::Pet<E, Claims = C> + Send + Sync,
E: std::fmt::Debug + Send + Sync + 'static,
{ {
#[allow(clippy::redundant_closure)] #[allow(clippy::redundant_closure)]
let validation = let validation =
@ -630,7 +673,7 @@ where
let result = api_impl let result = api_impl
.as_ref() .as_ref()
.update_pet_with_form(method, host, cookies, path_params, body) .update_pet_with_form(&method, &host, &cookies, &path_params, &body)
.await; .await;
let mut response = Response::builder(); let mut response = Response::builder();
@ -642,10 +685,14 @@ where
response.body(Body::empty()) response.body(Body::empty())
} }
}, },
Err(_) => { Err(why) => {
// Application code returned an error. This should not happen, as the implementation should // Application code returned an error. This should not happen, as the implementation should
// return a valid response. // return a valid response.
response.status(500).body(Body::empty())
return api_impl
.as_ref()
.handle_error(&method, &host, &cookies, why)
.await;
} }
}; };
@ -665,7 +712,7 @@ fn upload_file_validation(
} }
/// UploadFile - POST /v2/pet/{petId}/uploadImage /// UploadFile - POST /v2/pet/{petId}/uploadImage
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
async fn upload_file<I, A, C>( async fn upload_file<I, A, E, C>(
method: Method, method: Method,
host: Host, host: Host,
cookies: CookieJar, cookies: CookieJar,
@ -675,7 +722,8 @@ async fn upload_file<I, A, C>(
) -> Result<Response, StatusCode> ) -> Result<Response, StatusCode>
where where
I: AsRef<A> + Send + Sync, I: AsRef<A> + Send + Sync,
A: apis::pet::Pet<Claims = C>, A: apis::pet::Pet<E, Claims = C> + Send + Sync,
E: std::fmt::Debug + Send + Sync + 'static,
{ {
#[allow(clippy::redundant_closure)] #[allow(clippy::redundant_closure)]
let validation = tokio::task::spawn_blocking(move || upload_file_validation(path_params)) let validation = tokio::task::spawn_blocking(move || upload_file_validation(path_params))
@ -691,7 +739,7 @@ where
let result = api_impl let result = api_impl
.as_ref() .as_ref()
.upload_file(method, host, cookies, path_params, body) .upload_file(&method, &host, &cookies, &path_params, &body)
.await; .await;
let mut response = Response::builder(); let mut response = Response::builder();
@ -722,10 +770,14 @@ where
response.body(Body::from(body_content)) response.body(Body::from(body_content))
} }
}, },
Err(_) => { Err(why) => {
// Application code returned an error. This should not happen, as the implementation should // Application code returned an error. This should not happen, as the implementation should
// return a valid response. // return a valid response.
response.status(500).body(Body::empty())
return api_impl
.as_ref()
.handle_error(&method, &host, &cookies, why)
.await;
} }
}; };
@ -745,7 +797,7 @@ fn delete_order_validation(
} }
/// DeleteOrder - DELETE /v2/store/order/{orderId} /// DeleteOrder - DELETE /v2/store/order/{orderId}
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
async fn delete_order<I, A, C>( async fn delete_order<I, A, E, C>(
method: Method, method: Method,
host: Host, host: Host,
cookies: CookieJar, cookies: CookieJar,
@ -754,7 +806,8 @@ async fn delete_order<I, A, C>(
) -> Result<Response, StatusCode> ) -> Result<Response, StatusCode>
where where
I: AsRef<A> + Send + Sync, I: AsRef<A> + Send + Sync,
A: apis::store::Store<Claims = C>, A: apis::store::Store<E, Claims = C> + Send + Sync,
E: std::fmt::Debug + Send + Sync + 'static,
{ {
#[allow(clippy::redundant_closure)] #[allow(clippy::redundant_closure)]
let validation = tokio::task::spawn_blocking(move || delete_order_validation(path_params)) let validation = tokio::task::spawn_blocking(move || delete_order_validation(path_params))
@ -770,7 +823,7 @@ where
let result = api_impl let result = api_impl
.as_ref() .as_ref()
.delete_order(method, host, cookies, path_params) .delete_order(&method, &host, &cookies, &path_params)
.await; .await;
let mut response = Response::builder(); let mut response = Response::builder();
@ -786,10 +839,14 @@ where
response.body(Body::empty()) response.body(Body::empty())
} }
}, },
Err(_) => { Err(why) => {
// Application code returned an error. This should not happen, as the implementation should // Application code returned an error. This should not happen, as the implementation should
// return a valid response. // return a valid response.
response.status(500).body(Body::empty())
return api_impl
.as_ref()
.handle_error(&method, &host, &cookies, why)
.await;
} }
}; };
@ -805,7 +862,7 @@ fn get_inventory_validation() -> std::result::Result<(), ValidationErrors> {
} }
/// GetInventory - GET /v2/store/inventory /// GetInventory - GET /v2/store/inventory
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
async fn get_inventory<I, A, C>( async fn get_inventory<I, A, E, C>(
method: Method, method: Method,
host: Host, host: Host,
cookies: CookieJar, cookies: CookieJar,
@ -814,7 +871,8 @@ async fn get_inventory<I, A, C>(
) -> Result<Response, StatusCode> ) -> Result<Response, StatusCode>
where where
I: AsRef<A> + Send + Sync, I: AsRef<A> + Send + Sync,
A: apis::store::Store<Claims = C> + apis::ApiKeyAuthHeader<Claims = C>, A: apis::store::Store<E, Claims = C> + apis::ApiKeyAuthHeader<Claims = C> + Send + Sync,
E: std::fmt::Debug + Send + Sync + 'static,
{ {
// Authentication // Authentication
let claims_in_header = api_impl let claims_in_header = api_impl
@ -843,7 +901,7 @@ where
let result = api_impl let result = api_impl
.as_ref() .as_ref()
.get_inventory(method, host, cookies, claims) .get_inventory(&method, &host, &cookies, &claims)
.await; .await;
let mut response = Response::builder(); let mut response = Response::builder();
@ -874,10 +932,14 @@ where
response.body(Body::from(body_content)) response.body(Body::from(body_content))
} }
}, },
Err(_) => { Err(why) => {
// Application code returned an error. This should not happen, as the implementation should // Application code returned an error. This should not happen, as the implementation should
// return a valid response. // return a valid response.
response.status(500).body(Body::empty())
return api_impl
.as_ref()
.handle_error(&method, &host, &cookies, why)
.await;
} }
}; };
@ -897,7 +959,7 @@ fn get_order_by_id_validation(
} }
/// GetOrderById - GET /v2/store/order/{orderId} /// GetOrderById - GET /v2/store/order/{orderId}
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
async fn get_order_by_id<I, A, C>( async fn get_order_by_id<I, A, E, C>(
method: Method, method: Method,
host: Host, host: Host,
cookies: CookieJar, cookies: CookieJar,
@ -906,7 +968,8 @@ async fn get_order_by_id<I, A, C>(
) -> Result<Response, StatusCode> ) -> Result<Response, StatusCode>
where where
I: AsRef<A> + Send + Sync, I: AsRef<A> + Send + Sync,
A: apis::store::Store<Claims = C>, A: apis::store::Store<E, Claims = C> + Send + Sync,
E: std::fmt::Debug + Send + Sync + 'static,
{ {
#[allow(clippy::redundant_closure)] #[allow(clippy::redundant_closure)]
let validation = tokio::task::spawn_blocking(move || get_order_by_id_validation(path_params)) let validation = tokio::task::spawn_blocking(move || get_order_by_id_validation(path_params))
@ -922,7 +985,7 @@ where
let result = api_impl let result = api_impl
.as_ref() .as_ref()
.get_order_by_id(method, host, cookies, path_params) .get_order_by_id(&method, &host, &cookies, &path_params)
.await; .await;
let mut response = Response::builder(); let mut response = Response::builder();
@ -954,10 +1017,14 @@ where
response.body(Body::empty()) response.body(Body::empty())
} }
}, },
Err(_) => { Err(why) => {
// Application code returned an error. This should not happen, as the implementation should // Application code returned an error. This should not happen, as the implementation should
// return a valid response. // return a valid response.
response.status(500).body(Body::empty())
return api_impl
.as_ref()
.handle_error(&method, &host, &cookies, why)
.await;
} }
}; };
@ -985,7 +1052,7 @@ fn place_order_validation(
} }
/// PlaceOrder - POST /v2/store/order /// PlaceOrder - POST /v2/store/order
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
async fn place_order<I, A, C>( async fn place_order<I, A, E, C>(
method: Method, method: Method,
host: Host, host: Host,
cookies: CookieJar, cookies: CookieJar,
@ -994,7 +1061,8 @@ async fn place_order<I, A, C>(
) -> Result<Response, StatusCode> ) -> Result<Response, StatusCode>
where where
I: AsRef<A> + Send + Sync, I: AsRef<A> + Send + Sync,
A: apis::store::Store<Claims = C>, A: apis::store::Store<E, Claims = C> + Send + Sync,
E: std::fmt::Debug + Send + Sync + 'static,
{ {
#[allow(clippy::redundant_closure)] #[allow(clippy::redundant_closure)]
let validation = tokio::task::spawn_blocking(move || place_order_validation(body)) let validation = tokio::task::spawn_blocking(move || place_order_validation(body))
@ -1010,7 +1078,7 @@ where
let result = api_impl let result = api_impl
.as_ref() .as_ref()
.place_order(method, host, cookies, body) .place_order(&method, &host, &cookies, &body)
.await; .await;
let mut response = Response::builder(); let mut response = Response::builder();
@ -1038,10 +1106,14 @@ where
response.body(Body::empty()) response.body(Body::empty())
} }
}, },
Err(_) => { Err(why) => {
// Application code returned an error. This should not happen, as the implementation should // Application code returned an error. This should not happen, as the implementation should
// return a valid response. // return a valid response.
response.status(500).body(Body::empty())
return api_impl
.as_ref()
.handle_error(&method, &host, &cookies, why)
.await;
} }
}; };
@ -1069,7 +1141,7 @@ fn create_user_validation(
} }
/// CreateUser - POST /v2/user /// CreateUser - POST /v2/user
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
async fn create_user<I, A, C>( async fn create_user<I, A, E, C>(
method: Method, method: Method,
host: Host, host: Host,
cookies: CookieJar, cookies: CookieJar,
@ -1079,7 +1151,8 @@ async fn create_user<I, A, C>(
) -> Result<Response, StatusCode> ) -> Result<Response, StatusCode>
where where
I: AsRef<A> + Send + Sync, I: AsRef<A> + Send + Sync,
A: apis::user::User<Claims = C> + apis::ApiKeyAuthHeader<Claims = C>, A: apis::user::User<E, Claims = C> + apis::ApiKeyAuthHeader<Claims = C> + Send + Sync,
E: std::fmt::Debug + Send + Sync + 'static,
{ {
// Authentication // Authentication
let claims_in_header = api_impl let claims_in_header = api_impl
@ -1108,7 +1181,7 @@ where
let result = api_impl let result = api_impl
.as_ref() .as_ref()
.create_user(method, host, cookies, claims, body) .create_user(&method, &host, &cookies, &claims, &body)
.await; .await;
let mut response = Response::builder(); let mut response = Response::builder();
@ -1120,10 +1193,14 @@ where
response.body(Body::empty()) response.body(Body::empty())
} }
}, },
Err(_) => { Err(why) => {
// Application code returned an error. This should not happen, as the implementation should // Application code returned an error. This should not happen, as the implementation should
// return a valid response. // return a valid response.
response.status(500).body(Body::empty())
return api_impl
.as_ref()
.handle_error(&method, &host, &cookies, why)
.await;
} }
}; };
@ -1151,7 +1228,7 @@ fn create_users_with_array_input_validation(
} }
/// CreateUsersWithArrayInput - POST /v2/user/createWithArray /// CreateUsersWithArrayInput - POST /v2/user/createWithArray
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
async fn create_users_with_array_input<I, A, C>( async fn create_users_with_array_input<I, A, E, C>(
method: Method, method: Method,
host: Host, host: Host,
cookies: CookieJar, cookies: CookieJar,
@ -1161,7 +1238,8 @@ async fn create_users_with_array_input<I, A, C>(
) -> Result<Response, StatusCode> ) -> Result<Response, StatusCode>
where where
I: AsRef<A> + Send + Sync, I: AsRef<A> + Send + Sync,
A: apis::user::User<Claims = C> + apis::ApiKeyAuthHeader<Claims = C>, A: apis::user::User<E, Claims = C> + apis::ApiKeyAuthHeader<Claims = C> + Send + Sync,
E: std::fmt::Debug + Send + Sync + 'static,
{ {
// Authentication // Authentication
let claims_in_header = api_impl let claims_in_header = api_impl
@ -1191,7 +1269,7 @@ where
let result = api_impl let result = api_impl
.as_ref() .as_ref()
.create_users_with_array_input(method, host, cookies, claims, body) .create_users_with_array_input(&method, &host, &cookies, &claims, &body)
.await; .await;
let mut response = Response::builder(); let mut response = Response::builder();
@ -1203,10 +1281,14 @@ where
response.body(Body::empty()) response.body(Body::empty())
} }
}, },
Err(_) => { Err(why) => {
// Application code returned an error. This should not happen, as the implementation should // Application code returned an error. This should not happen, as the implementation should
// return a valid response. // return a valid response.
response.status(500).body(Body::empty())
return api_impl
.as_ref()
.handle_error(&method, &host, &cookies, why)
.await;
} }
}; };
@ -1234,7 +1316,7 @@ fn create_users_with_list_input_validation(
} }
/// CreateUsersWithListInput - POST /v2/user/createWithList /// CreateUsersWithListInput - POST /v2/user/createWithList
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
async fn create_users_with_list_input<I, A, C>( async fn create_users_with_list_input<I, A, E, C>(
method: Method, method: Method,
host: Host, host: Host,
cookies: CookieJar, cookies: CookieJar,
@ -1244,7 +1326,8 @@ async fn create_users_with_list_input<I, A, C>(
) -> Result<Response, StatusCode> ) -> Result<Response, StatusCode>
where where
I: AsRef<A> + Send + Sync, I: AsRef<A> + Send + Sync,
A: apis::user::User<Claims = C> + apis::ApiKeyAuthHeader<Claims = C>, A: apis::user::User<E, Claims = C> + apis::ApiKeyAuthHeader<Claims = C> + Send + Sync,
E: std::fmt::Debug + Send + Sync + 'static,
{ {
// Authentication // Authentication
let claims_in_header = api_impl let claims_in_header = api_impl
@ -1274,7 +1357,7 @@ where
let result = api_impl let result = api_impl
.as_ref() .as_ref()
.create_users_with_list_input(method, host, cookies, claims, body) .create_users_with_list_input(&method, &host, &cookies, &claims, &body)
.await; .await;
let mut response = Response::builder(); let mut response = Response::builder();
@ -1286,10 +1369,14 @@ where
response.body(Body::empty()) response.body(Body::empty())
} }
}, },
Err(_) => { Err(why) => {
// Application code returned an error. This should not happen, as the implementation should // Application code returned an error. This should not happen, as the implementation should
// return a valid response. // return a valid response.
response.status(500).body(Body::empty())
return api_impl
.as_ref()
.handle_error(&method, &host, &cookies, why)
.await;
} }
}; };
@ -1309,7 +1396,7 @@ fn delete_user_validation(
} }
/// DeleteUser - DELETE /v2/user/{username} /// DeleteUser - DELETE /v2/user/{username}
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
async fn delete_user<I, A, C>( async fn delete_user<I, A, E, C>(
method: Method, method: Method,
host: Host, host: Host,
cookies: CookieJar, cookies: CookieJar,
@ -1319,7 +1406,8 @@ async fn delete_user<I, A, C>(
) -> Result<Response, StatusCode> ) -> Result<Response, StatusCode>
where where
I: AsRef<A> + Send + Sync, I: AsRef<A> + Send + Sync,
A: apis::user::User<Claims = C> + apis::ApiKeyAuthHeader<Claims = C>, A: apis::user::User<E, Claims = C> + apis::ApiKeyAuthHeader<Claims = C> + Send + Sync,
E: std::fmt::Debug + Send + Sync + 'static,
{ {
// Authentication // Authentication
let claims_in_header = api_impl let claims_in_header = api_impl
@ -1348,7 +1436,7 @@ where
let result = api_impl let result = api_impl
.as_ref() .as_ref()
.delete_user(method, host, cookies, claims, path_params) .delete_user(&method, &host, &cookies, &claims, &path_params)
.await; .await;
let mut response = Response::builder(); let mut response = Response::builder();
@ -1364,10 +1452,14 @@ where
response.body(Body::empty()) response.body(Body::empty())
} }
}, },
Err(_) => { Err(why) => {
// Application code returned an error. This should not happen, as the implementation should // Application code returned an error. This should not happen, as the implementation should
// return a valid response. // return a valid response.
response.status(500).body(Body::empty())
return api_impl
.as_ref()
.handle_error(&method, &host, &cookies, why)
.await;
} }
}; };
@ -1387,7 +1479,7 @@ fn get_user_by_name_validation(
} }
/// GetUserByName - GET /v2/user/{username} /// GetUserByName - GET /v2/user/{username}
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
async fn get_user_by_name<I, A, C>( async fn get_user_by_name<I, A, E, C>(
method: Method, method: Method,
host: Host, host: Host,
cookies: CookieJar, cookies: CookieJar,
@ -1396,7 +1488,8 @@ async fn get_user_by_name<I, A, C>(
) -> Result<Response, StatusCode> ) -> Result<Response, StatusCode>
where where
I: AsRef<A> + Send + Sync, I: AsRef<A> + Send + Sync,
A: apis::user::User<Claims = C>, A: apis::user::User<E, Claims = C> + Send + Sync,
E: std::fmt::Debug + Send + Sync + 'static,
{ {
#[allow(clippy::redundant_closure)] #[allow(clippy::redundant_closure)]
let validation = tokio::task::spawn_blocking(move || get_user_by_name_validation(path_params)) let validation = tokio::task::spawn_blocking(move || get_user_by_name_validation(path_params))
@ -1412,7 +1505,7 @@ where
let result = api_impl let result = api_impl
.as_ref() .as_ref()
.get_user_by_name(method, host, cookies, path_params) .get_user_by_name(&method, &host, &cookies, &path_params)
.await; .await;
let mut response = Response::builder(); let mut response = Response::builder();
@ -1444,10 +1537,14 @@ where
response.body(Body::empty()) response.body(Body::empty())
} }
}, },
Err(_) => { Err(why) => {
// Application code returned an error. This should not happen, as the implementation should // Application code returned an error. This should not happen, as the implementation should
// return a valid response. // return a valid response.
response.status(500).body(Body::empty())
return api_impl
.as_ref()
.handle_error(&method, &host, &cookies, why)
.await;
} }
}; };
@ -1467,7 +1564,7 @@ fn login_user_validation(
} }
/// LoginUser - GET /v2/user/login /// LoginUser - GET /v2/user/login
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
async fn login_user<I, A, C>( async fn login_user<I, A, E, C>(
method: Method, method: Method,
host: Host, host: Host,
cookies: CookieJar, cookies: CookieJar,
@ -1476,7 +1573,8 @@ async fn login_user<I, A, C>(
) -> Result<Response, StatusCode> ) -> Result<Response, StatusCode>
where where
I: AsRef<A> + Send + Sync, I: AsRef<A> + Send + Sync,
A: apis::user::User<Claims = C>, A: apis::user::User<E, Claims = C> + Send + Sync,
E: std::fmt::Debug + Send + Sync + 'static,
{ {
#[allow(clippy::redundant_closure)] #[allow(clippy::redundant_closure)]
let validation = tokio::task::spawn_blocking(move || login_user_validation(query_params)) let validation = tokio::task::spawn_blocking(move || login_user_validation(query_params))
@ -1492,7 +1590,7 @@ where
let result = api_impl let result = api_impl
.as_ref() .as_ref()
.login_user(method, host, cookies, query_params) .login_user(&method, &host, &cookies, &query_params)
.await; .await;
let mut response = Response::builder(); let mut response = Response::builder();
@ -1573,10 +1671,14 @@ where
response.body(Body::empty()) response.body(Body::empty())
} }
}, },
Err(_) => { Err(why) => {
// Application code returned an error. This should not happen, as the implementation should // Application code returned an error. This should not happen, as the implementation should
// return a valid response. // return a valid response.
response.status(500).body(Body::empty())
return api_impl
.as_ref()
.handle_error(&method, &host, &cookies, why)
.await;
} }
}; };
@ -1592,7 +1694,7 @@ fn logout_user_validation() -> std::result::Result<(), ValidationErrors> {
} }
/// LogoutUser - GET /v2/user/logout /// LogoutUser - GET /v2/user/logout
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
async fn logout_user<I, A, C>( async fn logout_user<I, A, E, C>(
method: Method, method: Method,
host: Host, host: Host,
cookies: CookieJar, cookies: CookieJar,
@ -1601,7 +1703,8 @@ async fn logout_user<I, A, C>(
) -> Result<Response, StatusCode> ) -> Result<Response, StatusCode>
where where
I: AsRef<A> + Send + Sync, I: AsRef<A> + Send + Sync,
A: apis::user::User<Claims = C> + apis::ApiKeyAuthHeader<Claims = C>, A: apis::user::User<E, Claims = C> + apis::ApiKeyAuthHeader<Claims = C> + Send + Sync,
E: std::fmt::Debug + Send + Sync + 'static,
{ {
// Authentication // Authentication
let claims_in_header = api_impl let claims_in_header = api_impl
@ -1630,7 +1733,7 @@ where
let result = api_impl let result = api_impl
.as_ref() .as_ref()
.logout_user(method, host, cookies, claims) .logout_user(&method, &host, &cookies, &claims)
.await; .await;
let mut response = Response::builder(); let mut response = Response::builder();
@ -1642,10 +1745,14 @@ where
response.body(Body::empty()) response.body(Body::empty())
} }
}, },
Err(_) => { Err(why) => {
// Application code returned an error. This should not happen, as the implementation should // Application code returned an error. This should not happen, as the implementation should
// return a valid response. // return a valid response.
response.status(500).body(Body::empty())
return api_impl
.as_ref()
.handle_error(&method, &host, &cookies, why)
.await;
} }
}; };
@ -1675,7 +1782,7 @@ fn update_user_validation(
} }
/// UpdateUser - PUT /v2/user/{username} /// UpdateUser - PUT /v2/user/{username}
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
async fn update_user<I, A, C>( async fn update_user<I, A, E, C>(
method: Method, method: Method,
host: Host, host: Host,
cookies: CookieJar, cookies: CookieJar,
@ -1686,7 +1793,8 @@ async fn update_user<I, A, C>(
) -> Result<Response, StatusCode> ) -> Result<Response, StatusCode>
where where
I: AsRef<A> + Send + Sync, I: AsRef<A> + Send + Sync,
A: apis::user::User<Claims = C> + apis::ApiKeyAuthHeader<Claims = C>, A: apis::user::User<E, Claims = C> + apis::ApiKeyAuthHeader<Claims = C> + Send + Sync,
E: std::fmt::Debug + Send + Sync + 'static,
{ {
// Authentication // Authentication
let claims_in_header = api_impl let claims_in_header = api_impl
@ -1715,7 +1823,7 @@ where
let result = api_impl let result = api_impl
.as_ref() .as_ref()
.update_user(method, host, cookies, claims, path_params, body) .update_user(&method, &host, &cookies, &claims, &path_params, &body)
.await; .await;
let mut response = Response::builder(); let mut response = Response::builder();
@ -1731,10 +1839,14 @@ where
response.body(Body::empty()) response.body(Body::empty())
} }
}, },
Err(_) => { Err(why) => {
// Application code returned an error. This should not happen, as the implementation should // Application code returned an error. This should not happen, as the implementation should
// return a valid response. // return a valid response.
response.status(500).body(Body::empty())
return api_impl
.as_ref()
.handle_error(&method, &host, &cookies, why)
.await;
} }
}; };

View File

@ -1 +1 @@
7.11.0-SNAPSHOT 7.12.0-SNAPSHOT

View File

@ -40,7 +40,7 @@ tokio = { version = "1", default-features = false, features = [
] } ] }
tracing = { version = "0.1", features = ["attributes"] } tracing = { version = "0.1", features = ["attributes"] }
uuid = { version = "1", features = ["serde"] } uuid = { version = "1", features = ["serde"] }
validator = { version = "0.19", features = ["derive"] } validator = { version = "0.20", features = ["derive"] }
[dev-dependencies] [dev-dependencies]
tracing-subscriber = "0.3" tracing-subscriber = "0.3"

View File

@ -12,7 +12,7 @@ server, you can easily generate a server stub.
To see how to make this your own, look here: [README]((https://openapi-generator.tech)) To see how to make this your own, look here: [README]((https://openapi-generator.tech))
- API version: 1.0 - API version: 1.0
- Generator version: 7.11.0-SNAPSHOT - Generator version: 7.12.0-SNAPSHOT
@ -43,16 +43,18 @@ struct ServerImpl {
#[allow(unused_variables)] #[allow(unused_variables)]
#[async_trait] #[async_trait]
impl ping-bearer-auth::Api for ServerImpl { impl ping_bearer_auth::apis::default::Api for ServerImpl {
// API implementation goes here // API implementation goes here
} }
impl ping_bearer_auth::apis::ErrorHandler for ServerImpl {}
pub async fn start_server(addr: &str) { pub async fn start_server(addr: &str) {
// initialize tracing // initialize tracing
tracing_subscriber::fmt::init(); tracing_subscriber::fmt::init();
// Init Axum router // Init Axum router
let app = ping-bearer-auth::server::new(Arc::new(ServerImpl)); let app = ping_bearer_auth::server::new(Arc::new(ServerImpl));
// Add layers to the router // Add layers to the router
let app = app.layer(...); let app = app.layer(...);

View File

@ -18,12 +18,12 @@ pub enum PingGetResponse {
/// Default /// Default
#[async_trait] #[async_trait]
#[allow(clippy::ptr_arg)] #[allow(clippy::ptr_arg)]
pub trait Default { pub trait Default<E: std::fmt::Debug + Send + Sync + 'static = ()>: super::ErrorHandler<E> {
/// PingGet - GET /ping /// PingGet - GET /ping
async fn ping_get( async fn ping_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<PingGetResponse, ()>; ) -> Result<PingGetResponse, E>;
} }

View File

@ -1 +1,21 @@
pub mod default; pub mod default;
// Error handler for unhandled errors.
#[async_trait::async_trait]
pub trait ErrorHandler<E: std::fmt::Debug + Send + Sync + 'static = ()> {
#[allow(unused_variables)]
#[tracing::instrument(skip_all)]
async fn handle_error(
&self,
method: &::http::Method,
host: &axum::extract::Host,
cookies: &axum_extra::extract::CookieJar,
error: E,
) -> Result<axum::response::Response, http::StatusCode> {
tracing::error!("Unhandled error: {:?}", error);
axum::response::Response::builder()
.status(http::StatusCode::INTERNAL_SERVER_ERROR)
.body(axum::body::Body::empty())
.map_err(|_| http::StatusCode::INTERNAL_SERVER_ERROR)
}
}

View File

@ -13,14 +13,15 @@ use crate::{header, types::*};
use crate::{apis, models}; use crate::{apis, models};
/// Setup API Server. /// Setup API Server.
pub fn new<I, A>(api_impl: I) -> Router pub fn new<I, A, E>(api_impl: I) -> Router
where where
I: AsRef<A> + Clone + Send + Sync + 'static, I: AsRef<A> + Clone + Send + Sync + 'static,
A: apis::default::Default + 'static, A: apis::default::Default<E> + Send + Sync + 'static,
E: std::fmt::Debug + Send + Sync + 'static,
{ {
// build our application with a route // build our application with a route
Router::new() Router::new()
.route("/ping", get(ping_get::<I, A>)) .route("/ping", get(ping_get::<I, A, E>))
.with_state(api_impl) .with_state(api_impl)
} }
@ -30,7 +31,7 @@ fn ping_get_validation() -> std::result::Result<(), ValidationErrors> {
} }
/// PingGet - GET /ping /// PingGet - GET /ping
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
async fn ping_get<I, A>( async fn ping_get<I, A, E>(
method: Method, method: Method,
host: Host, host: Host,
cookies: CookieJar, cookies: CookieJar,
@ -38,7 +39,8 @@ async fn ping_get<I, A>(
) -> Result<Response, StatusCode> ) -> Result<Response, StatusCode>
where where
I: AsRef<A> + Send + Sync, I: AsRef<A> + Send + Sync,
A: apis::default::Default, A: apis::default::Default<E> + Send + Sync,
E: std::fmt::Debug + Send + Sync + 'static,
{ {
#[allow(clippy::redundant_closure)] #[allow(clippy::redundant_closure)]
let validation = tokio::task::spawn_blocking(move || ping_get_validation()) let validation = tokio::task::spawn_blocking(move || ping_get_validation())
@ -52,7 +54,7 @@ where
.map_err(|_| StatusCode::BAD_REQUEST); .map_err(|_| StatusCode::BAD_REQUEST);
}; };
let result = api_impl.as_ref().ping_get(method, host, cookies).await; let result = api_impl.as_ref().ping_get(&method, &host, &cookies).await;
let mut response = Response::builder(); let mut response = Response::builder();
@ -63,10 +65,14 @@ where
response.body(Body::empty()) response.body(Body::empty())
} }
}, },
Err(_) => { Err(why) => {
// Application code returned an error. This should not happen, as the implementation should // Application code returned an error. This should not happen, as the implementation should
// return a valid response. // return a valid response.
response.status(500).body(Body::empty())
return api_impl
.as_ref()
.handle_error(&method, &host, &cookies, why)
.await;
} }
}; };

View File

@ -40,7 +40,7 @@ tokio = { version = "1", default-features = false, features = [
] } ] }
tracing = { version = "0.1", features = ["attributes"] } tracing = { version = "0.1", features = ["attributes"] }
uuid = { version = "1", features = ["serde"] } uuid = { version = "1", features = ["serde"] }
validator = { version = "0.19", features = ["derive"] } validator = { version = "0.20", features = ["derive"] }
[dev-dependencies] [dev-dependencies]
tracing-subscriber = "0.3" tracing-subscriber = "0.3"

View File

@ -12,7 +12,7 @@ server, you can easily generate a server stub.
To see how to make this your own, look here: [README]((https://openapi-generator.tech)) To see how to make this your own, look here: [README]((https://openapi-generator.tech))
- API version: 0.1.9 - API version: 0.1.9
- Generator version: 7.11.0-SNAPSHOT - Generator version: 7.12.0-SNAPSHOT
@ -43,16 +43,18 @@ struct ServerImpl {
#[allow(unused_variables)] #[allow(unused_variables)]
#[async_trait] #[async_trait]
impl rust-axum-header-uui::Api for ServerImpl { impl rust_axum_header_uui::apis::default::Api for ServerImpl {
// API implementation goes here // API implementation goes here
} }
impl rust_axum_header_uui::apis::ErrorHandler for ServerImpl {}
pub async fn start_server(addr: &str) { pub async fn start_server(addr: &str) {
// initialize tracing // initialize tracing
tracing_subscriber::fmt::init(); tracing_subscriber::fmt::init();
// Init Axum router // Init Axum router
let app = rust-axum-header-uui::server::new(Arc::new(ServerImpl)); let app = rust_axum_header_uui::server::new(Arc::new(ServerImpl));
// Add layers to the router // Add layers to the router
let app = app.layer(...); let app = app.layer(...);

View File

@ -18,13 +18,13 @@ pub enum UsersPostResponse {
/// Default /// Default
#[async_trait] #[async_trait]
#[allow(clippy::ptr_arg)] #[allow(clippy::ptr_arg)]
pub trait Default { pub trait Default<E: std::fmt::Debug + Send + Sync + 'static = ()>: super::ErrorHandler<E> {
/// UsersPost - POST /users /// UsersPost - POST /users
async fn users_post( async fn users_post(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
header_params: models::UsersPostHeaderParams, header_params: &models::UsersPostHeaderParams,
) -> Result<UsersPostResponse, ()>; ) -> Result<UsersPostResponse, E>;
} }

View File

@ -1 +1,21 @@
pub mod default; pub mod default;
// Error handler for unhandled errors.
#[async_trait::async_trait]
pub trait ErrorHandler<E: std::fmt::Debug + Send + Sync + 'static = ()> {
#[allow(unused_variables)]
#[tracing::instrument(skip_all)]
async fn handle_error(
&self,
method: &::http::Method,
host: &axum::extract::Host,
cookies: &axum_extra::extract::CookieJar,
error: E,
) -> Result<axum::response::Response, http::StatusCode> {
tracing::error!("Unhandled error: {:?}", error);
axum::response::Response::builder()
.status(http::StatusCode::INTERNAL_SERVER_ERROR)
.body(axum::body::Body::empty())
.map_err(|_| http::StatusCode::INTERNAL_SERVER_ERROR)
}
}

View File

@ -13,14 +13,15 @@ use crate::{header, types::*};
use crate::{apis, models}; use crate::{apis, models};
/// Setup API Server. /// Setup API Server.
pub fn new<I, A>(api_impl: I) -> Router pub fn new<I, A, E>(api_impl: I) -> Router
where where
I: AsRef<A> + Clone + Send + Sync + 'static, I: AsRef<A> + Clone + Send + Sync + 'static,
A: apis::default::Default + 'static, A: apis::default::Default<E> + Send + Sync + 'static,
E: std::fmt::Debug + Send + Sync + 'static,
{ {
// build our application with a route // build our application with a route
Router::new() Router::new()
.route("/users", post(users_post::<I, A>)) .route("/users", post(users_post::<I, A, E>))
.with_state(api_impl) .with_state(api_impl)
} }
@ -34,7 +35,7 @@ fn users_post_validation(
} }
/// UsersPost - POST /users /// UsersPost - POST /users
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
async fn users_post<I, A>( async fn users_post<I, A, E>(
method: Method, method: Method,
host: Host, host: Host,
cookies: CookieJar, cookies: CookieJar,
@ -43,7 +44,8 @@ async fn users_post<I, A>(
) -> Result<Response, StatusCode> ) -> Result<Response, StatusCode>
where where
I: AsRef<A> + Send + Sync, I: AsRef<A> + Send + Sync,
A: apis::default::Default, A: apis::default::Default<E> + Send + Sync,
E: std::fmt::Debug + Send + Sync + 'static,
{ {
// Header parameters // Header parameters
let header_params = { let header_params = {
@ -92,7 +94,7 @@ where
let result = api_impl let result = api_impl
.as_ref() .as_ref()
.users_post(method, host, cookies, header_params) .users_post(&method, &host, &cookies, &header_params)
.await; .await;
let mut response = Response::builder(); let mut response = Response::builder();
@ -123,10 +125,14 @@ where
response.body(Body::from(body_content)) response.body(Body::from(body_content))
} }
}, },
Err(_) => { Err(why) => {
// Application code returned an error. This should not happen, as the implementation should // Application code returned an error. This should not happen, as the implementation should
// return a valid response. // return a valid response.
response.status(500).body(Body::empty())
return api_impl
.as_ref()
.handle_error(&method, &host, &cookies, why)
.await;
} }
}; };

View File

@ -1 +1 @@
7.11.0-SNAPSHOT 7.12.0-SNAPSHOT

View File

@ -40,7 +40,7 @@ tokio = { version = "1", default-features = false, features = [
] } ] }
tracing = { version = "0.1", features = ["attributes"] } tracing = { version = "0.1", features = ["attributes"] }
uuid = { version = "1", features = ["serde"] } uuid = { version = "1", features = ["serde"] }
validator = { version = "0.19", features = ["derive"] } validator = { version = "0.20", features = ["derive"] }
[dev-dependencies] [dev-dependencies]
tracing-subscriber = "0.3" tracing-subscriber = "0.3"

View File

@ -12,7 +12,7 @@ server, you can easily generate a server stub.
To see how to make this your own, look here: [README]((https://openapi-generator.tech)) To see how to make this your own, look here: [README]((https://openapi-generator.tech))
- API version: 0.0.1 - API version: 0.0.1
- Generator version: 7.11.0-SNAPSHOT - Generator version: 7.12.0-SNAPSHOT
@ -43,16 +43,18 @@ struct ServerImpl {
#[allow(unused_variables)] #[allow(unused_variables)]
#[async_trait] #[async_trait]
impl rust-axum-oneof::Api for ServerImpl { impl rust_axum_oneof::apis::default::Api for ServerImpl {
// API implementation goes here // API implementation goes here
} }
impl rust_axum_oneof::apis::ErrorHandler for ServerImpl {}
pub async fn start_server(addr: &str) { pub async fn start_server(addr: &str) {
// initialize tracing // initialize tracing
tracing_subscriber::fmt::init(); tracing_subscriber::fmt::init();
// Init Axum router // Init Axum router
let app = rust-axum-oneof::server::new(Arc::new(ServerImpl)); let app = rust_axum_oneof::server::new(Arc::new(ServerImpl));
// Add layers to the router // Add layers to the router
let app = app.layer(...); let app = app.layer(...);

View File

@ -18,13 +18,13 @@ pub enum FooResponse {
/// Default /// Default
#[async_trait] #[async_trait]
#[allow(clippy::ptr_arg)] #[allow(clippy::ptr_arg)]
pub trait Default { pub trait Default<E: std::fmt::Debug + Send + Sync + 'static = ()>: super::ErrorHandler<E> {
/// Foo - POST / /// Foo - POST /
async fn foo( async fn foo(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
body: models::Message, body: &models::Message,
) -> Result<FooResponse, ()>; ) -> Result<FooResponse, E>;
} }

View File

@ -1 +1,21 @@
pub mod default; pub mod default;
// Error handler for unhandled errors.
#[async_trait::async_trait]
pub trait ErrorHandler<E: std::fmt::Debug + Send + Sync + 'static = ()> {
#[allow(unused_variables)]
#[tracing::instrument(skip_all)]
async fn handle_error(
&self,
method: &::http::Method,
host: &axum::extract::Host,
cookies: &axum_extra::extract::CookieJar,
error: E,
) -> Result<axum::response::Response, http::StatusCode> {
tracing::error!("Unhandled error: {:?}", error);
axum::response::Response::builder()
.status(http::StatusCode::INTERNAL_SERVER_ERROR)
.body(axum::body::Body::empty())
.map_err(|_| http::StatusCode::INTERNAL_SERVER_ERROR)
}
}

View File

@ -13,14 +13,15 @@ use crate::{header, types::*};
use crate::{apis, models}; use crate::{apis, models};
/// Setup API Server. /// Setup API Server.
pub fn new<I, A>(api_impl: I) -> Router pub fn new<I, A, E>(api_impl: I) -> Router
where where
I: AsRef<A> + Clone + Send + Sync + 'static, I: AsRef<A> + Clone + Send + Sync + 'static,
A: apis::default::Default + 'static, A: apis::default::Default<E> + Send + Sync + 'static,
E: std::fmt::Debug + Send + Sync + 'static,
{ {
// build our application with a route // build our application with a route
Router::new() Router::new()
.route("/", post(foo::<I, A>)) .route("/", post(foo::<I, A, E>))
.with_state(api_impl) .with_state(api_impl)
} }
@ -42,7 +43,7 @@ fn foo_validation(
} }
/// Foo - POST / /// Foo - POST /
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
async fn foo<I, A>( async fn foo<I, A, E>(
method: Method, method: Method,
host: Host, host: Host,
cookies: CookieJar, cookies: CookieJar,
@ -51,7 +52,8 @@ async fn foo<I, A>(
) -> Result<Response, StatusCode> ) -> Result<Response, StatusCode>
where where
I: AsRef<A> + Send + Sync, I: AsRef<A> + Send + Sync,
A: apis::default::Default, A: apis::default::Default<E> + Send + Sync,
E: std::fmt::Debug + Send + Sync + 'static,
{ {
#[allow(clippy::redundant_closure)] #[allow(clippy::redundant_closure)]
let validation = tokio::task::spawn_blocking(move || foo_validation(body)) let validation = tokio::task::spawn_blocking(move || foo_validation(body))
@ -65,7 +67,7 @@ where
.map_err(|_| StatusCode::BAD_REQUEST); .map_err(|_| StatusCode::BAD_REQUEST);
}; };
let result = api_impl.as_ref().foo(method, host, cookies, body).await; let result = api_impl.as_ref().foo(&method, &host, &cookies, &body).await;
let mut response = Response::builder(); let mut response = Response::builder();
@ -95,10 +97,14 @@ where
response.body(Body::from(body_content)) response.body(Body::from(body_content))
} }
}, },
Err(_) => { Err(why) => {
// Application code returned an error. This should not happen, as the implementation should // Application code returned an error. This should not happen, as the implementation should
// return a valid response. // return a valid response.
response.status(500).body(Body::empty())
return api_impl
.as_ref()
.handle_error(&method, &host, &cookies, why)
.await;
} }
}; };

View File

@ -1 +1 @@
7.11.0-SNAPSHOT 7.12.0-SNAPSHOT

View File

@ -40,7 +40,7 @@ tokio = { version = "1", default-features = false, features = [
] } ] }
tracing = { version = "0.1", features = ["attributes"] } tracing = { version = "0.1", features = ["attributes"] }
uuid = { version = "1", features = ["serde"] } uuid = { version = "1", features = ["serde"] }
validator = { version = "0.19", features = ["derive"] } validator = { version = "0.20", features = ["derive"] }
[dev-dependencies] [dev-dependencies]
tracing-subscriber = "0.3" tracing-subscriber = "0.3"

View File

@ -12,7 +12,7 @@ server, you can easily generate a server stub.
To see how to make this your own, look here: [README]((https://openapi-generator.tech)) To see how to make this your own, look here: [README]((https://openapi-generator.tech))
- API version: 2.3.4 - API version: 2.3.4
- Generator version: 7.11.0-SNAPSHOT - Generator version: 7.12.0-SNAPSHOT
@ -43,16 +43,18 @@ struct ServerImpl {
#[allow(unused_variables)] #[allow(unused_variables)]
#[async_trait] #[async_trait]
impl rust-server-test::Api for ServerImpl { impl rust_server_test::apis::default::Api for ServerImpl {
// API implementation goes here // API implementation goes here
} }
impl rust_server_test::apis::ErrorHandler for ServerImpl {}
pub async fn start_server(addr: &str) { pub async fn start_server(addr: &str) {
// initialize tracing // initialize tracing
tracing_subscriber::fmt::init(); tracing_subscriber::fmt::init();
// Init Axum router // Init Axum router
let app = rust-server-test::server::new(Arc::new(ServerImpl)); let app = rust_server_test::server::new(Arc::new(ServerImpl));
// Add layers to the router // Add layers to the router
let app = app.layer(...); let app = app.layer(...);

View File

@ -82,90 +82,90 @@ pub enum SoloObjectPostResponse {
/// Default /// Default
#[async_trait] #[async_trait]
#[allow(clippy::ptr_arg)] #[allow(clippy::ptr_arg)]
pub trait Default { pub trait Default<E: std::fmt::Debug + Send + Sync + 'static = ()>: super::ErrorHandler<E> {
/// AllOfGet - GET /allOf /// AllOfGet - GET /allOf
async fn all_of_get( async fn all_of_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<AllOfGetResponse, ()>; ) -> Result<AllOfGetResponse, E>;
/// A dummy endpoint to make the spec valid.. /// A dummy endpoint to make the spec valid..
/// ///
/// DummyGet - GET /dummy /// DummyGet - GET /dummy
async fn dummy_get( async fn dummy_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<DummyGetResponse, ()>; ) -> Result<DummyGetResponse, E>;
/// DummyPut - PUT /dummy /// DummyPut - PUT /dummy
async fn dummy_put( async fn dummy_put(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
body: models::FooDummyPutRequest, body: &models::FooDummyPutRequest,
) -> Result<DummyPutResponse, ()>; ) -> Result<DummyPutResponse, E>;
/// Get a file. /// Get a file.
/// ///
/// FileResponseGet - GET /file_response /// FileResponseGet - GET /file_response
async fn file_response_get( async fn file_response_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<FileResponseGetResponse, ()>; ) -> Result<FileResponseGetResponse, E>;
/// GetStructuredYaml - GET /get-structured-yaml /// GetStructuredYaml - GET /get-structured-yaml
async fn get_structured_yaml( async fn get_structured_yaml(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<GetStructuredYamlResponse, ()>; ) -> Result<GetStructuredYamlResponse, E>;
/// Test HTML handling. /// Test HTML handling.
/// ///
/// HtmlPost - POST /html /// HtmlPost - POST /html
async fn html_post( async fn html_post(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
body: String, body: &String,
) -> Result<HtmlPostResponse, ()>; ) -> Result<HtmlPostResponse, E>;
/// PostYaml - POST /post-yaml /// PostYaml - POST /post-yaml
async fn post_yaml( async fn post_yaml(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
body: String, body: &String,
) -> Result<PostYamlResponse, ()>; ) -> Result<PostYamlResponse, E>;
/// Get an arbitrary JSON blob.. /// Get an arbitrary JSON blob..
/// ///
/// RawJsonGet - GET /raw_json /// RawJsonGet - GET /raw_json
async fn raw_json_get( async fn raw_json_get(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
) -> Result<RawJsonGetResponse, ()>; ) -> Result<RawJsonGetResponse, E>;
/// Send an arbitrary JSON blob. /// Send an arbitrary JSON blob.
/// ///
/// SoloObjectPost - POST /solo-object /// SoloObjectPost - POST /solo-object
async fn solo_object_post( async fn solo_object_post(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
body: crate::types::Object, body: &crate::types::Object,
) -> Result<SoloObjectPostResponse, ()>; ) -> Result<SoloObjectPostResponse, E>;
} }

View File

@ -1 +1,21 @@
pub mod default; pub mod default;
// Error handler for unhandled errors.
#[async_trait::async_trait]
pub trait ErrorHandler<E: std::fmt::Debug + Send + Sync + 'static = ()> {
#[allow(unused_variables)]
#[tracing::instrument(skip_all)]
async fn handle_error(
&self,
method: &::http::Method,
host: &axum::extract::Host,
cookies: &axum_extra::extract::CookieJar,
error: E,
) -> Result<axum::response::Response, http::StatusCode> {
tracing::error!("Unhandled error: {:?}", error);
axum::response::Response::builder()
.status(http::StatusCode::INTERNAL_SERVER_ERROR)
.body(axum::body::Body::empty())
.map_err(|_| http::StatusCode::INTERNAL_SERVER_ERROR)
}
}

View File

@ -13,21 +13,25 @@ use crate::{header, types::*};
use crate::{apis, models}; use crate::{apis, models};
/// Setup API Server. /// Setup API Server.
pub fn new<I, A>(api_impl: I) -> Router pub fn new<I, A, E>(api_impl: I) -> Router
where where
I: AsRef<A> + Clone + Send + Sync + 'static, I: AsRef<A> + Clone + Send + Sync + 'static,
A: apis::default::Default + 'static, A: apis::default::Default<E> + Send + Sync + 'static,
E: std::fmt::Debug + Send + Sync + 'static,
{ {
// build our application with a route // build our application with a route
Router::new() Router::new()
.route("/allOf", get(all_of_get::<I, A>)) .route("/allOf", get(all_of_get::<I, A, E>))
.route("/dummy", get(dummy_get::<I, A>).put(dummy_put::<I, A>)) .route(
.route("/file_response", get(file_response_get::<I, A>)) "/dummy",
.route("/get-structured-yaml", get(get_structured_yaml::<I, A>)) get(dummy_get::<I, A, E>).put(dummy_put::<I, A, E>),
.route("/html", post(html_post::<I, A>)) )
.route("/post-yaml", post(post_yaml::<I, A>)) .route("/file_response", get(file_response_get::<I, A, E>))
.route("/raw_json", get(raw_json_get::<I, A>)) .route("/get-structured-yaml", get(get_structured_yaml::<I, A, E>))
.route("/solo-object", post(solo_object_post::<I, A>)) .route("/html", post(html_post::<I, A, E>))
.route("/post-yaml", post(post_yaml::<I, A, E>))
.route("/raw_json", get(raw_json_get::<I, A, E>))
.route("/solo-object", post(solo_object_post::<I, A, E>))
.with_state(api_impl) .with_state(api_impl)
} }
@ -37,7 +41,7 @@ fn all_of_get_validation() -> std::result::Result<(), ValidationErrors> {
} }
/// AllOfGet - GET /allOf /// AllOfGet - GET /allOf
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
async fn all_of_get<I, A>( async fn all_of_get<I, A, E>(
method: Method, method: Method,
host: Host, host: Host,
cookies: CookieJar, cookies: CookieJar,
@ -45,7 +49,8 @@ async fn all_of_get<I, A>(
) -> Result<Response, StatusCode> ) -> Result<Response, StatusCode>
where where
I: AsRef<A> + Send + Sync, I: AsRef<A> + Send + Sync,
A: apis::default::Default, A: apis::default::Default<E> + Send + Sync,
E: std::fmt::Debug + Send + Sync + 'static,
{ {
#[allow(clippy::redundant_closure)] #[allow(clippy::redundant_closure)]
let validation = tokio::task::spawn_blocking(move || all_of_get_validation()) let validation = tokio::task::spawn_blocking(move || all_of_get_validation())
@ -59,7 +64,7 @@ where
.map_err(|_| StatusCode::BAD_REQUEST); .map_err(|_| StatusCode::BAD_REQUEST);
}; };
let result = api_impl.as_ref().all_of_get(method, host, cookies).await; let result = api_impl.as_ref().all_of_get(&method, &host, &cookies).await;
let mut response = Response::builder(); let mut response = Response::builder();
@ -89,10 +94,14 @@ where
response.body(Body::from(body_content)) response.body(Body::from(body_content))
} }
}, },
Err(_) => { Err(why) => {
// Application code returned an error. This should not happen, as the implementation should // Application code returned an error. This should not happen, as the implementation should
// return a valid response. // return a valid response.
response.status(500).body(Body::empty())
return api_impl
.as_ref()
.handle_error(&method, &host, &cookies, why)
.await;
} }
}; };
@ -108,7 +117,7 @@ fn dummy_get_validation() -> std::result::Result<(), ValidationErrors> {
} }
/// DummyGet - GET /dummy /// DummyGet - GET /dummy
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
async fn dummy_get<I, A>( async fn dummy_get<I, A, E>(
method: Method, method: Method,
host: Host, host: Host,
cookies: CookieJar, cookies: CookieJar,
@ -116,7 +125,8 @@ async fn dummy_get<I, A>(
) -> Result<Response, StatusCode> ) -> Result<Response, StatusCode>
where where
I: AsRef<A> + Send + Sync, I: AsRef<A> + Send + Sync,
A: apis::default::Default, A: apis::default::Default<E> + Send + Sync,
E: std::fmt::Debug + Send + Sync + 'static,
{ {
#[allow(clippy::redundant_closure)] #[allow(clippy::redundant_closure)]
let validation = tokio::task::spawn_blocking(move || dummy_get_validation()) let validation = tokio::task::spawn_blocking(move || dummy_get_validation())
@ -130,7 +140,7 @@ where
.map_err(|_| StatusCode::BAD_REQUEST); .map_err(|_| StatusCode::BAD_REQUEST);
}; };
let result = api_impl.as_ref().dummy_get(method, host, cookies).await; let result = api_impl.as_ref().dummy_get(&method, &host, &cookies).await;
let mut response = Response::builder(); let mut response = Response::builder();
@ -141,10 +151,14 @@ where
response.body(Body::empty()) response.body(Body::empty())
} }
}, },
Err(_) => { Err(why) => {
// Application code returned an error. This should not happen, as the implementation should // Application code returned an error. This should not happen, as the implementation should
// return a valid response. // return a valid response.
response.status(500).body(Body::empty())
return api_impl
.as_ref()
.handle_error(&method, &host, &cookies, why)
.await;
} }
}; };
@ -172,7 +186,7 @@ fn dummy_put_validation(
} }
/// DummyPut - PUT /dummy /// DummyPut - PUT /dummy
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
async fn dummy_put<I, A>( async fn dummy_put<I, A, E>(
method: Method, method: Method,
host: Host, host: Host,
cookies: CookieJar, cookies: CookieJar,
@ -181,7 +195,8 @@ async fn dummy_put<I, A>(
) -> Result<Response, StatusCode> ) -> Result<Response, StatusCode>
where where
I: AsRef<A> + Send + Sync, I: AsRef<A> + Send + Sync,
A: apis::default::Default, A: apis::default::Default<E> + Send + Sync,
E: std::fmt::Debug + Send + Sync + 'static,
{ {
#[allow(clippy::redundant_closure)] #[allow(clippy::redundant_closure)]
let validation = tokio::task::spawn_blocking(move || dummy_put_validation(body)) let validation = tokio::task::spawn_blocking(move || dummy_put_validation(body))
@ -197,7 +212,7 @@ where
let result = api_impl let result = api_impl
.as_ref() .as_ref()
.dummy_put(method, host, cookies, body) .dummy_put(&method, &host, &cookies, &body)
.await; .await;
let mut response = Response::builder(); let mut response = Response::builder();
@ -209,10 +224,14 @@ where
response.body(Body::empty()) response.body(Body::empty())
} }
}, },
Err(_) => { Err(why) => {
// Application code returned an error. This should not happen, as the implementation should // Application code returned an error. This should not happen, as the implementation should
// return a valid response. // return a valid response.
response.status(500).body(Body::empty())
return api_impl
.as_ref()
.handle_error(&method, &host, &cookies, why)
.await;
} }
}; };
@ -228,7 +247,7 @@ fn file_response_get_validation() -> std::result::Result<(), ValidationErrors> {
} }
/// FileResponseGet - GET /file_response /// FileResponseGet - GET /file_response
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
async fn file_response_get<I, A>( async fn file_response_get<I, A, E>(
method: Method, method: Method,
host: Host, host: Host,
cookies: CookieJar, cookies: CookieJar,
@ -236,7 +255,8 @@ async fn file_response_get<I, A>(
) -> Result<Response, StatusCode> ) -> Result<Response, StatusCode>
where where
I: AsRef<A> + Send + Sync, I: AsRef<A> + Send + Sync,
A: apis::default::Default, A: apis::default::Default<E> + Send + Sync,
E: std::fmt::Debug + Send + Sync + 'static,
{ {
#[allow(clippy::redundant_closure)] #[allow(clippy::redundant_closure)]
let validation = tokio::task::spawn_blocking(move || file_response_get_validation()) let validation = tokio::task::spawn_blocking(move || file_response_get_validation())
@ -252,7 +272,7 @@ where
let result = api_impl let result = api_impl
.as_ref() .as_ref()
.file_response_get(method, host, cookies) .file_response_get(&method, &host, &cookies)
.await; .await;
let mut response = Response::builder(); let mut response = Response::builder();
@ -283,10 +303,14 @@ where
response.body(Body::from(body_content)) response.body(Body::from(body_content))
} }
}, },
Err(_) => { Err(why) => {
// Application code returned an error. This should not happen, as the implementation should // Application code returned an error. This should not happen, as the implementation should
// return a valid response. // return a valid response.
response.status(500).body(Body::empty())
return api_impl
.as_ref()
.handle_error(&method, &host, &cookies, why)
.await;
} }
}; };
@ -302,7 +326,7 @@ fn get_structured_yaml_validation() -> std::result::Result<(), ValidationErrors>
} }
/// GetStructuredYaml - GET /get-structured-yaml /// GetStructuredYaml - GET /get-structured-yaml
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
async fn get_structured_yaml<I, A>( async fn get_structured_yaml<I, A, E>(
method: Method, method: Method,
host: Host, host: Host,
cookies: CookieJar, cookies: CookieJar,
@ -310,7 +334,8 @@ async fn get_structured_yaml<I, A>(
) -> Result<Response, StatusCode> ) -> Result<Response, StatusCode>
where where
I: AsRef<A> + Send + Sync, I: AsRef<A> + Send + Sync,
A: apis::default::Default, A: apis::default::Default<E> + Send + Sync,
E: std::fmt::Debug + Send + Sync + 'static,
{ {
#[allow(clippy::redundant_closure)] #[allow(clippy::redundant_closure)]
let validation = tokio::task::spawn_blocking(move || get_structured_yaml_validation()) let validation = tokio::task::spawn_blocking(move || get_structured_yaml_validation())
@ -326,7 +351,7 @@ where
let result = api_impl let result = api_impl
.as_ref() .as_ref()
.get_structured_yaml(method, host, cookies) .get_structured_yaml(&method, &host, &cookies)
.await; .await;
let mut response = Response::builder(); let mut response = Response::builder();
@ -350,10 +375,14 @@ where
response.body(Body::from(body_content)) response.body(Body::from(body_content))
} }
}, },
Err(_) => { Err(why) => {
// Application code returned an error. This should not happen, as the implementation should // Application code returned an error. This should not happen, as the implementation should
// return a valid response. // return a valid response.
response.status(500).body(Body::empty())
return api_impl
.as_ref()
.handle_error(&method, &host, &cookies, why)
.await;
} }
}; };
@ -375,7 +404,7 @@ fn html_post_validation(body: String) -> std::result::Result<(String,), Validati
} }
/// HtmlPost - POST /html /// HtmlPost - POST /html
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
async fn html_post<I, A>( async fn html_post<I, A, E>(
method: Method, method: Method,
host: Host, host: Host,
cookies: CookieJar, cookies: CookieJar,
@ -384,7 +413,8 @@ async fn html_post<I, A>(
) -> Result<Response, StatusCode> ) -> Result<Response, StatusCode>
where where
I: AsRef<A> + Send + Sync, I: AsRef<A> + Send + Sync,
A: apis::default::Default, A: apis::default::Default<E> + Send + Sync,
E: std::fmt::Debug + Send + Sync + 'static,
{ {
#[allow(clippy::redundant_closure)] #[allow(clippy::redundant_closure)]
let validation = tokio::task::spawn_blocking(move || html_post_validation(body)) let validation = tokio::task::spawn_blocking(move || html_post_validation(body))
@ -400,7 +430,7 @@ where
let result = api_impl let result = api_impl
.as_ref() .as_ref()
.html_post(method, host, cookies, body) .html_post(&method, &host, &cookies, &body)
.await; .await;
let mut response = Response::builder(); let mut response = Response::builder();
@ -424,10 +454,14 @@ where
response.body(Body::from(body_content)) response.body(Body::from(body_content))
} }
}, },
Err(_) => { Err(why) => {
// Application code returned an error. This should not happen, as the implementation should // Application code returned an error. This should not happen, as the implementation should
// return a valid response. // return a valid response.
response.status(500).body(Body::empty())
return api_impl
.as_ref()
.handle_error(&method, &host, &cookies, why)
.await;
} }
}; };
@ -449,7 +483,7 @@ fn post_yaml_validation(body: String) -> std::result::Result<(String,), Validati
} }
/// PostYaml - POST /post-yaml /// PostYaml - POST /post-yaml
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
async fn post_yaml<I, A>( async fn post_yaml<I, A, E>(
method: Method, method: Method,
host: Host, host: Host,
cookies: CookieJar, cookies: CookieJar,
@ -458,7 +492,8 @@ async fn post_yaml<I, A>(
) -> Result<Response, StatusCode> ) -> Result<Response, StatusCode>
where where
I: AsRef<A> + Send + Sync, I: AsRef<A> + Send + Sync,
A: apis::default::Default, A: apis::default::Default<E> + Send + Sync,
E: std::fmt::Debug + Send + Sync + 'static,
{ {
#[allow(clippy::redundant_closure)] #[allow(clippy::redundant_closure)]
let validation = tokio::task::spawn_blocking(move || post_yaml_validation(body)) let validation = tokio::task::spawn_blocking(move || post_yaml_validation(body))
@ -474,7 +509,7 @@ where
let result = api_impl let result = api_impl
.as_ref() .as_ref()
.post_yaml(method, host, cookies, body) .post_yaml(&method, &host, &cookies, &body)
.await; .await;
let mut response = Response::builder(); let mut response = Response::builder();
@ -486,10 +521,14 @@ where
response.body(Body::empty()) response.body(Body::empty())
} }
}, },
Err(_) => { Err(why) => {
// Application code returned an error. This should not happen, as the implementation should // Application code returned an error. This should not happen, as the implementation should
// return a valid response. // return a valid response.
response.status(500).body(Body::empty())
return api_impl
.as_ref()
.handle_error(&method, &host, &cookies, why)
.await;
} }
}; };
@ -505,7 +544,7 @@ fn raw_json_get_validation() -> std::result::Result<(), ValidationErrors> {
} }
/// RawJsonGet - GET /raw_json /// RawJsonGet - GET /raw_json
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
async fn raw_json_get<I, A>( async fn raw_json_get<I, A, E>(
method: Method, method: Method,
host: Host, host: Host,
cookies: CookieJar, cookies: CookieJar,
@ -513,7 +552,8 @@ async fn raw_json_get<I, A>(
) -> Result<Response, StatusCode> ) -> Result<Response, StatusCode>
where where
I: AsRef<A> + Send + Sync, I: AsRef<A> + Send + Sync,
A: apis::default::Default, A: apis::default::Default<E> + Send + Sync,
E: std::fmt::Debug + Send + Sync + 'static,
{ {
#[allow(clippy::redundant_closure)] #[allow(clippy::redundant_closure)]
let validation = tokio::task::spawn_blocking(move || raw_json_get_validation()) let validation = tokio::task::spawn_blocking(move || raw_json_get_validation())
@ -527,7 +567,10 @@ where
.map_err(|_| StatusCode::BAD_REQUEST); .map_err(|_| StatusCode::BAD_REQUEST);
}; };
let result = api_impl.as_ref().raw_json_get(method, host, cookies).await; let result = api_impl
.as_ref()
.raw_json_get(&method, &host, &cookies)
.await;
let mut response = Response::builder(); let mut response = Response::builder();
@ -557,10 +600,14 @@ where
response.body(Body::from(body_content)) response.body(Body::from(body_content))
} }
}, },
Err(_) => { Err(why) => {
// Application code returned an error. This should not happen, as the implementation should // Application code returned an error. This should not happen, as the implementation should
// return a valid response. // return a valid response.
response.status(500).body(Body::empty())
return api_impl
.as_ref()
.handle_error(&method, &host, &cookies, why)
.await;
} }
}; };
@ -587,7 +634,7 @@ fn solo_object_post_validation(
} }
/// SoloObjectPost - POST /solo-object /// SoloObjectPost - POST /solo-object
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
async fn solo_object_post<I, A>( async fn solo_object_post<I, A, E>(
method: Method, method: Method,
host: Host, host: Host,
cookies: CookieJar, cookies: CookieJar,
@ -596,7 +643,8 @@ async fn solo_object_post<I, A>(
) -> Result<Response, StatusCode> ) -> Result<Response, StatusCode>
where where
I: AsRef<A> + Send + Sync, I: AsRef<A> + Send + Sync,
A: apis::default::Default, A: apis::default::Default<E> + Send + Sync,
E: std::fmt::Debug + Send + Sync + 'static,
{ {
#[allow(clippy::redundant_closure)] #[allow(clippy::redundant_closure)]
let validation = tokio::task::spawn_blocking(move || solo_object_post_validation(body)) let validation = tokio::task::spawn_blocking(move || solo_object_post_validation(body))
@ -612,7 +660,7 @@ where
let result = api_impl let result = api_impl
.as_ref() .as_ref()
.solo_object_post(method, host, cookies, body) .solo_object_post(&method, &host, &cookies, &body)
.await; .await;
let mut response = Response::builder(); let mut response = Response::builder();
@ -624,10 +672,14 @@ where
response.body(Body::empty()) response.body(Body::empty())
} }
}, },
Err(_) => { Err(why) => {
// Application code returned an error. This should not happen, as the implementation should // Application code returned an error. This should not happen, as the implementation should
// return a valid response. // return a valid response.
response.status(500).body(Body::empty())
return api_impl
.as_ref()
.handle_error(&method, &host, &cookies, why)
.await;
} }
}; };

View File

@ -40,7 +40,7 @@ tokio = { version = "1", default-features = false, features = [
] } ] }
tracing = { version = "0.1", features = ["attributes"] } tracing = { version = "0.1", features = ["attributes"] }
uuid = { version = "1", features = ["serde"] } uuid = { version = "1", features = ["serde"] }
validator = { version = "0.19", features = ["derive"] } validator = { version = "0.20", features = ["derive"] }
[dev-dependencies] [dev-dependencies]
tracing-subscriber = "0.3" tracing-subscriber = "0.3"

View File

@ -12,7 +12,7 @@ server, you can easily generate a server stub.
To see how to make this your own, look here: [README]((https://openapi-generator.tech)) To see how to make this your own, look here: [README]((https://openapi-generator.tech))
- API version: 0.0.1 - API version: 0.0.1
- Generator version: 7.11.0-SNAPSHOT - Generator version: 7.12.0-SNAPSHOT
@ -43,16 +43,18 @@ struct ServerImpl {
#[allow(unused_variables)] #[allow(unused_variables)]
#[async_trait] #[async_trait]
impl rust-axum-validation-test::Api for ServerImpl { impl rust_axum_validation_test::apis::default::Api for ServerImpl {
// API implementation goes here // API implementation goes here
} }
impl rust_axum_validation_test::apis::ErrorHandler for ServerImpl {}
pub async fn start_server(addr: &str) { pub async fn start_server(addr: &str) {
// initialize tracing // initialize tracing
tracing_subscriber::fmt::init(); tracing_subscriber::fmt::init();
// Init Axum router // Init Axum router
let app = rust-axum-validation-test::server::new(Arc::new(ServerImpl)); let app = rust_axum_validation_test::server::new(Arc::new(ServerImpl));
// Add layers to the router // Add layers to the router
let app = app.layer(...); let app = app.layer(...);

View File

@ -18,13 +18,13 @@ pub enum MailPutResponse {
/// Default /// Default
#[async_trait] #[async_trait]
#[allow(clippy::ptr_arg)] #[allow(clippy::ptr_arg)]
pub trait Default { pub trait Default<E: std::fmt::Debug + Send + Sync + 'static = ()>: super::ErrorHandler<E> {
/// MailPut - PUT /mail /// MailPut - PUT /mail
async fn mail_put( async fn mail_put(
&self, &self,
method: Method, method: &Method,
host: Host, host: &Host,
cookies: CookieJar, cookies: &CookieJar,
body: models::Email, body: &models::Email,
) -> Result<MailPutResponse, ()>; ) -> Result<MailPutResponse, E>;
} }

View File

@ -1 +1,21 @@
pub mod default; pub mod default;
// Error handler for unhandled errors.
#[async_trait::async_trait]
pub trait ErrorHandler<E: std::fmt::Debug + Send + Sync + 'static = ()> {
#[allow(unused_variables)]
#[tracing::instrument(skip_all)]
async fn handle_error(
&self,
method: &::http::Method,
host: &axum::extract::Host,
cookies: &axum_extra::extract::CookieJar,
error: E,
) -> Result<axum::response::Response, http::StatusCode> {
tracing::error!("Unhandled error: {:?}", error);
axum::response::Response::builder()
.status(http::StatusCode::INTERNAL_SERVER_ERROR)
.body(axum::body::Body::empty())
.map_err(|_| http::StatusCode::INTERNAL_SERVER_ERROR)
}
}

View File

@ -13,20 +13,21 @@ use crate::{header, types::*};
use crate::{apis, models}; use crate::{apis, models};
/// Setup API Server. /// Setup API Server.
pub fn new<I, A>(api_impl: I) -> Router pub fn new<I, A, E>(api_impl: I) -> Router
where where
I: AsRef<A> + Clone + Send + Sync + 'static, I: AsRef<A> + Clone + Send + Sync + 'static,
A: apis::default::Default + 'static, A: apis::default::Default<E> + Send + Sync + 'static,
E: std::fmt::Debug + Send + Sync + 'static,
{ {
// build our application with a route // build our application with a route
Router::new() Router::new()
.route("/mail", put(mail_put::<I, A>)) .route("/mail", put(mail_put::<I, A, E>))
.with_state(api_impl) .with_state(api_impl)
} }
/// MailPut - PUT /mail /// MailPut - PUT /mail
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
async fn mail_put<I, A>( async fn mail_put<I, A, E>(
method: Method, method: Method,
host: Host, host: Host,
cookies: CookieJar, cookies: CookieJar,
@ -35,11 +36,12 @@ async fn mail_put<I, A>(
) -> Result<Response, StatusCode> ) -> Result<Response, StatusCode>
where where
I: AsRef<A> + Send + Sync, I: AsRef<A> + Send + Sync,
A: apis::default::Default, A: apis::default::Default<E> + Send + Sync,
E: std::fmt::Debug + Send + Sync + 'static,
{ {
let result = api_impl let result = api_impl
.as_ref() .as_ref()
.mail_put(method, host, cookies, body) .mail_put(&method, &host, &cookies, &body)
.await; .await;
let mut response = Response::builder(); let mut response = Response::builder();
@ -51,10 +53,14 @@ where
response.body(Body::empty()) response.body(Body::empty())
} }
}, },
Err(_) => { Err(why) => {
// Application code returned an error. This should not happen, as the implementation should // Application code returned an error. This should not happen, as the implementation should
// return a valid response. // return a valid response.
response.status(500).body(Body::empty())
return api_impl
.as_ref()
.handle_error(&method, &host, &cookies, why)
.await;
} }
}; };