Skip to content

Commit 7b3143b

Browse files
svix-jplattejplatte
authored andcommitted
Replace map_response(IntoResponse::into_response) with custom service wrapper
1 parent 902a394 commit 7b3143b

File tree

3 files changed

+69
-11
lines changed

3 files changed

+69
-11
lines changed

axum/src/middleware/from_fn.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use crate::response::{IntoResponse, Response};
21
use axum_core::extract::{FromRequest, FromRequestParts, Request};
32
use futures_util::future::BoxFuture;
43
use std::{
@@ -11,10 +10,14 @@ use std::{
1110
task::{Context, Poll},
1211
};
1312
use tower::util::BoxCloneSyncService;
14-
use tower::ServiceBuilder;
1513
use tower_layer::Layer;
1614
use tower_service::Service;
1715

16+
use crate::{
17+
response::{IntoResponse, Response},
18+
util::MapIntoResponse,
19+
};
20+
1821
/// Create a middleware from an async function.
1922
///
2023
/// `from_fn` requires the function given to
@@ -300,10 +303,7 @@ macro_rules! impl_service {
300303
Err(rejection) => return rejection.into_response(),
301304
};
302305

303-
let inner = ServiceBuilder::new()
304-
.layer_fn(BoxCloneSyncService::new)
305-
.map_response(IntoResponse::into_response)
306-
.service(ready_inner);
306+
let inner = BoxCloneSyncService::new(MapIntoResponse::new(ready_inner));
307307
let next = Next { inner };
308308

309309
f($($ty,)* $last, next).await.into_response()

axum/src/routing/route.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::{
22
body::{Body, HttpBody},
33
response::Response,
4+
util::MapIntoResponse,
45
};
56
use axum_core::{extract::Request, response::IntoResponse};
67
use bytes::Bytes;
@@ -17,7 +18,7 @@ use std::{
1718
task::{ready, Context, Poll},
1819
};
1920
use tower::{
20-
util::{BoxCloneSyncService, MapErrLayer, MapResponseLayer, Oneshot},
21+
util::{BoxCloneSyncService, MapErrLayer, Oneshot},
2122
ServiceExt,
2223
};
2324
use tower_layer::Layer;
@@ -36,9 +37,7 @@ impl<E> Route<E> {
3637
T::Response: IntoResponse + 'static,
3738
T::Future: Send + 'static,
3839
{
39-
Self(BoxCloneSyncService::new(
40-
svc.map_response(IntoResponse::into_response),
41-
))
40+
Self(BoxCloneSyncService::new(MapIntoResponse::new(svc)))
4241
}
4342

4443
/// Variant of [`Route::call`] that takes ownership of the route to avoid cloning.

axum/src/util.rs

+60-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
1+
use axum_core::response::{IntoResponse, Response};
12
use pin_project_lite::pin_project;
2-
use std::{ops::Deref, sync::Arc};
3+
use std::{
4+
future::Future,
5+
ops::Deref,
6+
pin::Pin,
7+
sync::Arc,
8+
task::{ready, Context, Poll},
9+
};
10+
use tower::Service;
311

412
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
513
pub(crate) struct PercentDecodedStr(Arc<str>);
@@ -37,6 +45,57 @@ pin_project! {
3745
}
3846
}
3947

48+
#[derive(Clone)]
49+
pub(crate) struct MapIntoResponse<S> {
50+
inner: S,
51+
}
52+
53+
impl<S> MapIntoResponse<S> {
54+
pub(crate) fn new(inner: S) -> Self {
55+
Self { inner }
56+
}
57+
}
58+
59+
impl<B, S> Service<http::Request<B>> for MapIntoResponse<S>
60+
where
61+
S: Service<http::Request<B>>,
62+
S::Response: IntoResponse,
63+
{
64+
type Response = Response;
65+
type Error = S::Error;
66+
type Future = MapIntoResponseFuture<S::Future>;
67+
68+
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
69+
self.inner.poll_ready(cx)
70+
}
71+
72+
fn call(&mut self, req: http::Request<B>) -> Self::Future {
73+
MapIntoResponseFuture {
74+
inner: self.inner.call(req),
75+
}
76+
}
77+
}
78+
79+
pin_project! {
80+
pub(crate) struct MapIntoResponseFuture<F> {
81+
#[pin]
82+
inner: F,
83+
}
84+
}
85+
86+
impl<F, T, E> Future for MapIntoResponseFuture<F>
87+
where
88+
F: Future<Output = Result<T, E>>,
89+
T: IntoResponse,
90+
{
91+
type Output = Result<Response, E>;
92+
93+
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
94+
let res = ready!(self.project().inner.poll(cx)?);
95+
Poll::Ready(Ok(res.into_response()))
96+
}
97+
}
98+
4099
pub(crate) fn try_downcast<T, K>(k: K) -> Result<T, K>
41100
where
42101
T: 'static,

0 commit comments

Comments
 (0)