@@ -3,13 +3,15 @@ use crate::{
33 response:: { IntoResponse , Response } ,
44 BoxError ,
55} ;
6+ use axum_core:: extract:: { FromRequest , RequestParts } ;
7+ use futures_util:: future:: BoxFuture ;
68use http:: Request ;
7- use pin_project_lite:: pin_project;
89use std:: {
910 any:: type_name,
1011 convert:: Infallible ,
1112 fmt,
1213 future:: Future ,
14+ marker:: PhantomData ,
1315 pin:: Pin ,
1416 task:: { Context , Poll } ,
1517} ;
@@ -23,8 +25,8 @@ use tower_service::Service;
2325/// `from_fn` requires the function given to
2426///
2527/// 1. Be an `async fn`.
26- /// 2. Take [`Request<B>`](http::Request) as the first argument .
27- /// 3. Take [`Next<B>`](Next) as the second argument.
28+ /// 2. Take one or more [extractors] as the first arguments .
29+ /// 3. Take [`Next<B>`](Next) as the final argument.
2830/// 4. Return something that implements [`IntoResponse`].
2931///
3032/// # Example
@@ -62,6 +64,37 @@ use tower_service::Service;
6264/// # let app: Router = app;
6365/// ```
6466///
67+ /// # Running extractors
68+ ///
69+ /// ```rust
70+ /// use axum::{
71+ /// Router,
72+ /// extract::{TypedHeader, Query},
73+ /// headers::authorization::{Authorization, Bearer},
74+ /// http::Request,
75+ /// middleware::{self, Next},
76+ /// response::Response,
77+ /// routing::get,
78+ /// };
79+ /// use std::collections::HashMap;
80+ ///
81+ /// async fn my_middleware<B>(
82+ /// TypedHeader(auth): TypedHeader<Authorization<Bearer>>,
83+ /// Query(query_params): Query<HashMap<String, String>>,
84+ /// req: Request<B>,
85+ /// next: Next<B>,
86+ /// ) -> Response {
87+ /// // do something with `auth` and `query_params`...
88+ ///
89+ /// next.run(req).await
90+ /// }
91+ ///
92+ /// let app = Router::new()
93+ /// .route("/", get(|| async { /* ... */ }))
94+ /// .route_layer(middleware::from_fn(my_middleware));
95+ /// # let app: Router = app;
96+ /// ```
97+ ///
6598/// # Passing state
6699///
67100/// State can be passed to the function like so:
@@ -114,11 +147,10 @@ use tower_service::Service;
114147/// struct State { /* ... */ }
115148///
116149/// async fn my_middleware<B>(
150+ /// Extension(state): Extension<State>,
117151/// req: Request<B>,
118152/// next: Next<B>,
119153/// ) -> Response {
120- /// let state: &State = req.extensions().get().unwrap();
121- ///
122154/// // ...
123155/// # ().into_response()
124156/// }
@@ -134,35 +166,55 @@ use tower_service::Service;
134166/// );
135167/// # let app: Router = app;
136168/// ```
137- pub fn from_fn < F > ( f : F ) -> FromFnLayer < F > {
138- FromFnLayer { f }
169+ ///
170+ /// [extractors]: crate::extract::FromRequest
171+ pub fn from_fn < F , T > ( f : F ) -> FromFnLayer < F , T > {
172+ FromFnLayer {
173+ f,
174+ _extractor : PhantomData ,
175+ }
139176}
140177
141178/// A [`tower::Layer`] from an async function.
142179///
143180/// [`tower::Layer`] is used to apply middleware to [`Router`](crate::Router)'s.
144181///
145182/// Created with [`from_fn`]. See that function for more details.
146- #[ derive( Clone , Copy ) ]
147- pub struct FromFnLayer < F > {
183+ pub struct FromFnLayer < F , T > {
148184 f : F ,
185+ _extractor : PhantomData < fn ( ) -> T > ,
149186}
150187
151- impl < S , F > Layer < S > for FromFnLayer < F >
188+ impl < F , T > Clone for FromFnLayer < F , T >
152189where
153190 F : Clone ,
154191{
155- type Service = FromFn < F , S > ;
192+ fn clone ( & self ) -> Self {
193+ Self {
194+ f : self . f . clone ( ) ,
195+ _extractor : self . _extractor ,
196+ }
197+ }
198+ }
199+
200+ impl < F , T > Copy for FromFnLayer < F , T > where F : Copy { }
201+
202+ impl < S , F , T > Layer < S > for FromFnLayer < F , T >
203+ where
204+ F : Clone ,
205+ {
206+ type Service = FromFn < F , S , T > ;
156207
157208 fn layer ( & self , inner : S ) -> Self :: Service {
158209 FromFn {
159210 f : self . f . clone ( ) ,
160211 inner,
212+ _extractor : PhantomData ,
161213 }
162214 }
163215}
164216
165- impl < F > fmt:: Debug for FromFnLayer < F > {
217+ impl < F , T > fmt:: Debug for FromFnLayer < F , T > {
166218 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
167219 f. debug_struct ( "FromFnLayer" )
168220 // Write out the type name, without quoting it as `&type_name::<F>()` would
@@ -174,50 +226,94 @@ impl<F> fmt::Debug for FromFnLayer<F> {
174226/// A middleware created from an async function.
175227///
176228/// Created with [`from_fn`]. See that function for more details.
177- #[ derive( Clone , Copy ) ]
178- pub struct FromFn < F , S > {
229+ pub struct FromFn < F , S , T > {
179230 f : F ,
180231 inner : S ,
232+ _extractor : PhantomData < fn ( ) -> T > ,
181233}
182234
183- impl < F , Fut , Out , S , ReqBody , ResBody > Service < Request < ReqBody > > for FromFn < F , S >
235+ impl < F , S , T > Clone for FromFn < F , S , T >
184236where
185- F : FnMut ( Request < ReqBody > , Next < ReqBody > ) -> Fut ,
186- Fut : Future < Output = Out > ,
187- Out : IntoResponse ,
188- S : Service < Request < ReqBody > , Response = Response < ResBody > , Error = Infallible >
189- + Clone
190- + Send
191- + ' static ,
192- S :: Future : Send + ' static ,
193- ResBody : HttpBody < Data = Bytes > + Send + ' static ,
194- ResBody :: Error : Into < BoxError > ,
237+ F : Clone ,
238+ S : Clone ,
195239{
196- type Response = Response ;
197- type Error = Infallible ;
198- type Future = ResponseFuture < Fut > ;
199-
200- fn poll_ready ( & mut self , cx : & mut Context < ' _ > ) -> Poll < Result < ( ) , Self :: Error > > {
201- self . inner . poll_ready ( cx )
240+ fn clone ( & self ) -> Self {
241+ Self {
242+ f : self . f . clone ( ) ,
243+ inner : self . inner . clone ( ) ,
244+ _extractor : self . _extractor ,
245+ }
202246 }
247+ }
248+
249+ impl < F , S , T > Copy for FromFn < F , S , T >
250+ where
251+ F : Copy ,
252+ S : Copy ,
253+ {
254+ }
255+
256+ macro_rules! impl_service {
257+ ( $( $ty: ident) ,* $( , ) ? ) => {
258+ #[ allow( non_snake_case) ]
259+ impl <F , Fut , Out , S , ReqBody , ResBody , $( $ty, ) * > Service <Request <ReqBody >> for FromFn <F , S , ( $( $ty, ) * ) >
260+ where
261+ F : FnMut ( $( $ty) ,* , Next <ReqBody >) -> Fut + Clone + Send + ' static ,
262+ $( $ty: FromRequest <ReqBody > + Send , ) *
263+ Fut : Future <Output = Out > + Send + ' static ,
264+ Out : IntoResponse + ' static ,
265+ S : Service <Request <ReqBody >, Response = Response <ResBody >, Error = Infallible >
266+ + Clone
267+ + Send
268+ + ' static ,
269+ S :: Future : Send + ' static ,
270+ ReqBody : Send + ' static ,
271+ ResBody : HttpBody <Data = Bytes > + Send + ' static ,
272+ ResBody :: Error : Into <BoxError >,
273+ {
274+ type Response = Response ;
275+ type Error = Infallible ;
276+ type Future = ResponseFuture ;
203277
204- fn call ( & mut self , req : Request < ReqBody > ) -> Self :: Future {
205- let not_ready_inner = self . inner . clone ( ) ;
206- let ready_inner = std :: mem :: replace ( & mut self . inner , not_ready_inner ) ;
278+ fn poll_ready ( & mut self , cx : & mut Context < ' _ >) -> Poll < Result < ( ) , Self :: Error >> {
279+ self . inner. poll_ready ( cx )
280+ }
207281
208- let inner = ServiceBuilder :: new ( )
209- . boxed_clone ( )
210- . map_response_body ( body:: boxed)
211- . service ( ready_inner) ;
212- let next = Next { inner } ;
282+ fn call( & mut self , req: Request <ReqBody >) -> Self :: Future {
283+ let not_ready_inner = self . inner. clone( ) ;
284+ let ready_inner = std:: mem:: replace( & mut self . inner, not_ready_inner) ;
213285
214- ResponseFuture {
215- inner : ( self . f ) ( req, next) ,
286+ let mut f = self . f. clone( ) ;
287+
288+ let future = Box :: pin( async move {
289+ let mut parts = RequestParts :: new( req) ;
290+ $(
291+ let $ty = match $ty:: from_request( & mut parts) . await {
292+ Ok ( value) => value,
293+ Err ( rejection) => return rejection. into_response( ) ,
294+ } ;
295+ ) *
296+
297+ let inner = ServiceBuilder :: new( )
298+ . boxed_clone( )
299+ . map_response_body( body:: boxed)
300+ . service( ready_inner) ;
301+ let next = Next { inner } ;
302+
303+ f( $( $ty) ,* , next) . await . into_response( )
304+ } ) ;
305+
306+ ResponseFuture {
307+ inner: future
308+ }
309+ }
216310 }
217- }
311+ } ;
218312}
219313
220- impl < F , S > fmt:: Debug for FromFn < F , S >
314+ all_the_tuples ! ( impl_service) ;
315+
316+ impl < F , S , T > fmt:: Debug for FromFn < F , S , T >
221317where
222318 S : fmt:: Debug ,
223319{
@@ -252,27 +348,22 @@ impl<ReqBody> fmt::Debug for Next<ReqBody> {
252348 }
253349}
254350
255- pin_project ! {
256- /// Response future for [`FromFn`].
257- pub struct ResponseFuture <F > {
258- #[ pin]
259- inner: F ,
260- }
351+ /// Response future for [`FromFn`].
352+ pub struct ResponseFuture {
353+ inner : BoxFuture < ' static , Response > ,
261354}
262355
263- impl < F , Out > Future for ResponseFuture < F >
264- where
265- F : Future < Output = Out > ,
266- Out : IntoResponse ,
267- {
356+ impl Future for ResponseFuture {
268357 type Output = Result < Response , Infallible > ;
269358
270- fn poll ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Self :: Output > {
271- self . project ( )
272- . inner
273- . poll ( cx)
274- . map ( IntoResponse :: into_response)
275- . map ( Ok )
359+ fn poll ( mut self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Self :: Output > {
360+ self . inner . as_mut ( ) . poll ( cx) . map ( Ok )
361+ }
362+ }
363+
364+ impl fmt:: Debug for ResponseFuture {
365+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
366+ f. debug_struct ( "ResponseFuture" ) . finish ( )
276367 }
277368}
278369
0 commit comments