From 66c88fc24f4bab6bf2b9452b6575314f8336bfb6 Mon Sep 17 00:00:00 2001 From: tamasfe Date: Wed, 29 Nov 2023 13:03:36 +0100 Subject: [PATCH] feat(aide): sync axum router differences --- crates/aide/src/axum/mod.rs | 20 +++++- crates/aide/src/axum/routing.rs | 108 +++++++++++++++++++++++--------- 2 files changed, 95 insertions(+), 33 deletions(-) diff --git a/crates/aide/src/axum/mod.rs b/crates/aide/src/axum/mod.rs index 67f7b97..d56a630 100644 --- a/crates/aide/src/axum/mod.rs +++ b/crates/aide/src/axum/mod.rs @@ -183,7 +183,7 @@ use axum::{ handler::Handler, http::Request, response::IntoResponse, - routing::{IntoMakeService, Route}, + routing::{IntoMakeService, Route, RouterAsService, RouterIntoService}, Router, }; use indexmap::map::Entry; @@ -458,7 +458,7 @@ where self } - /// Alternative to [`nest_service`](Self::nest_service()) which besides nesting the service nests + /// Alternative to [`nest_service`](Self::nest_service) which besides nesting the service nests /// the generated documentation as well. /// /// Due to Rust's limitations, currently this function will not @@ -566,6 +566,22 @@ where self.router = self.router.fallback_service(svc); self } + + /// See [`axum::Router::as_service`] for details. + /// + /// Using this method will not generate API documentation. + #[must_use] + pub fn as_service(&mut self) -> RouterAsService<'_, B, S> { + self.router.as_service() + } + + /// See [`axum::Router::into_service`] for details. + /// + /// Using this method will not generate API documentation. + #[must_use] + pub fn into_service(self) -> RouterIntoService { + self.router.into_service() + } } impl ApiRouter<()> { diff --git a/crates/aide/src/axum/routing.rs b/crates/aide/src/axum/routing.rs index 9a9e1b4..41f93bc 100644 --- a/crates/aide/src/axum/routing.rs +++ b/crates/aide/src/axum/routing.rs @@ -8,8 +8,8 @@ use crate::{ openapi::{Operation, PathItem, ReferenceOr, Response, StatusCode}, Error, }; -use axum::body::{Body, HttpBody}; -use axum::routing::Route; +use axum::routing::{MethodFilter, Route}; +use axum::{body::Body, response::IntoResponse}; use axum::{ handler::Handler, routing::{self, MethodRouter}, @@ -33,6 +33,15 @@ pub struct ApiMethodRouter { pub(crate) router: MethodRouter, } +impl Clone for ApiMethodRouter { + fn clone(&self) -> Self { + Self { + operations: self.operations.clone(), + router: self.router.clone(), + } + } +} + impl From> for MethodRouter { fn from(router: ApiMethodRouter) -> Self { router.router @@ -233,48 +242,21 @@ where method_router_chain_method!(post, post_with); method_router_chain_method!(put, put_with); method_router_chain_method!(trace, trace_with); - - /// This method wraps a layer around the [`ApiMethodRouter`] - /// For further information see [`axum::routing::method_routing::MethodRouter::layer`] - pub fn layer(self, layer: L) -> ApiMethodRouter - where - L: Layer> + Clone + Send + 'static, - L::Service: Service, Response = http::response::Response, Error = NewError> - + Clone - + Send - + 'static, - >>::Future: Send + 'static, - Body: HttpBody + 'static, - NewError: 'static, - { - ApiMethodRouter { - router: self.router.layer(layer), - operations: self.operations, - } - } } impl ApiMethodRouter where S: Clone, { - /// Create a new, clean [`ApiMethodRouter`] based on [`MethodRouter::new()`](axum::routing::MethodRouter). + /// Create a new, empty [`ApiMethodRouter`] based on [`MethodRouter::new()`](axum::routing::MethodRouter). pub fn new() -> Self { Self { operations: IndexMap::default(), router: MethodRouter::::new(), } } - /// See [`axum::routing::MethodRouter`] and [`axum::extract::State`] for more information. - pub fn with_state(self, state: S) -> ApiMethodRouter { - let router = self.router.with_state(state); - ApiMethodRouter:: { - operations: self.operations, - router, - } - } - /// See [`axum::routing::MethodRouter::merge`] for more information. + /// See [`axum::routing::MethodRouter::merge`]. pub fn merge(mut self, other: M) -> Self where M: Into>, @@ -284,6 +266,70 @@ where self.router = self.router.merge(other.router); self } + + /// See [`axum::routing::method_routing::MethodRouter::layer`]. + pub fn layer(self, layer: L) -> ApiMethodRouter + where + L: Layer> + Clone + Send + 'static, + L::Service: Service> + Clone + Send + 'static, + >>::Response: IntoResponse + 'static, + >>::Error: Into + 'static, + >>::Future: Send + 'static, + E: 'static, + S: 'static, + NewError: 'static, + { + ApiMethodRouter { + router: self.router.layer(layer), + operations: self.operations, + } + } + + /// See [`axum::routing::method_routing::MethodRouter::with_state`]. + pub fn with_state(self, state: S) -> ApiMethodRouter { + ApiMethodRouter { + router: self.router.with_state(state), + operations: self.operations, + } + } + + /// See [`axum::routing::method_routing::MethodRouter::on_service`]. + pub fn on_service(mut self, filter: MethodFilter, svc: T) -> Self + where + T: Service, Error = E> + Clone + Send + 'static, + T::Response: IntoResponse + 'static, + T::Future: Send + 'static, + { + self.router = self.router.on_service(filter, svc); + self + } + + /// See [`axum::routing::method_routing::MethodRouter::fallback_service`]. + pub fn fallback_service(mut self, svc: T) -> Self + where + T: Service, Error = E> + Clone + Send + 'static, + T::Response: IntoResponse + 'static, + T::Future: Send + 'static, + { + self.router = self.router.fallback_service(svc); + self + } + + /// See [`axum::routing::method_routing::MethodRouter::route_layer`]. + pub fn route_layer(self, layer: L) -> ApiMethodRouter + where + L: Layer> + Clone + Send + 'static, + L::Service: Service, Error = E> + Clone + Send + 'static, + >>::Response: IntoResponse + 'static, + >>::Future: Send + 'static, + E: 'static, + S: 'static, + { + ApiMethodRouter { + router: self.router.route_layer(layer), + operations: self.operations, + } + } } impl Default for ApiMethodRouter