Skip to content

Commit 878b10f

Browse files
authored
util: unify and rename combinators (#499)
Currently, the `ServiceExt` trait has `with` and `try_with` methods for composing a `Service` with functions that modify the request type, and `map_err` and `map_ok` methods for composing a service with functions that modify the response type. Meanwhile, `ServiceBuilder` has `map_request` for composing a service with a request mapping function, and `map_response` for composing a service with a response-mapping function. These combinators are very similar in purpose, but are implemented using different middleware types that essentially duplicate the same behavior. Before releasing 0.4, we should probably unify these APIs. In particular, it would be good to de-duplicate the middleware service types, and to unify the naming. This commit makes the following changes: - Rename the `ServiceExt::with` and `ServiceExt::try_with` combinators to `map_request` and `try_map_request` - Rename the `ServiceExt::map_ok` combinator to `map_response` - Unify the `ServiceBuilder::map_request` and `ServiceExt::map_request` combinators to use the same `Service` type - Unify the `ServiceBuilder::map_response` and `ServiceExt::map_response` combinators to use the same `Service` type - Unify the `ServiceBuilder::map_err` and `ServiceExt::map_err` combinators to use the same `Service` type - Only take `FnOnce + Clone` when in response/err combinators, which require cloning into the future type. `MapRequest` and `TryMapRequest` now take `FnMut(Request)`s and don't clone them every time they're called - Reexport future types for combinators where it makes sense. - Add a `try_map_request` method to `ServiceBuilder` Closes #498 Signed-off-by: Eliza Weisman <[email protected]>
1 parent 0100800 commit 878b10f

File tree

10 files changed

+173
-336
lines changed

10 files changed

+173
-336
lines changed

tower/src/builder/mod.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,11 +197,23 @@ impl<L> ServiceBuilder<L> {
197197
f: F,
198198
) -> ServiceBuilder<Stack<crate::util::MapRequestLayer<F>, L>>
199199
where
200-
F: Fn(R1) -> R2,
200+
F: FnMut(R1) -> R2 + Clone,
201201
{
202202
self.layer(crate::util::MapRequestLayer::new(f))
203203
}
204204

205+
/// Fallibly one request type to another, or to an error.
206+
#[cfg(feature = "util")]
207+
pub fn try_map_request<F, R1, R2, E>(
208+
self,
209+
f: F,
210+
) -> ServiceBuilder<Stack<crate::util::TryMapRequestLayer<F>, L>>
211+
where
212+
F: FnMut(R1) -> Result<R2, E> + Clone,
213+
{
214+
self.layer(crate::util::TryMapRequestLayer::new(f))
215+
}
216+
205217
/// Map one response type to another.
206218
#[cfg(feature = "util")]
207219
pub fn map_response<F>(
@@ -211,6 +223,12 @@ impl<L> ServiceBuilder<L> {
211223
self.layer(crate::util::MapResponseLayer::new(f))
212224
}
213225

226+
/// Map one error type to another.
227+
#[cfg(feature = "util")]
228+
pub fn map_err<F>(self, f: F) -> ServiceBuilder<Stack<crate::util::MapErrLayer<F>, L>> {
229+
self.layer(crate::util::MapErrLayer::new(f))
230+
}
231+
214232
/// Obtains the underlying `Layer` implementation.
215233
pub fn into_inner(self) -> L {
216234
self.layer

tower/src/util/map/mod.rs

Lines changed: 0 additions & 7 deletions
This file was deleted.

tower/src/util/map/request.rs

Lines changed: 0 additions & 70 deletions
This file was deleted.

tower/src/util/map/response.rs

Lines changed: 0 additions & 118 deletions
This file was deleted.

tower/src/util/map_err.rs

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1-
use futures_util::{future::MapErr as MapErrFut, TryFutureExt};
1+
use futures_util::TryFutureExt;
22
use std::task::{Context, Poll};
33
use tower_layer::Layer;
44
use tower_service::Service;
55

6+
#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
7+
pub use futures_util::future::MapErr as MapErrFuture;
8+
69
/// Service returned by the [`map_err`] combinator.
710
///
811
/// [`map_err`]: crate::util::ServiceExt::map_err
@@ -12,6 +15,14 @@ pub struct MapErr<S, F> {
1215
f: F,
1316
}
1417

18+
/// A [`Layer`] that produces a [`MapErr`] service.
19+
///
20+
/// [`Layer`]: tower_layer::Layer
21+
#[derive(Debug)]
22+
pub struct MapErrLayer<F> {
23+
f: F,
24+
}
25+
1526
impl<S, F> MapErr<S, F> {
1627
/// Creates a new [`MapErr`] service.
1728
pub fn new(inner: S, f: F) -> Self {
@@ -26,25 +37,19 @@ where
2637
{
2738
type Response = S::Response;
2839
type Error = Error;
29-
type Future = MapErrFut<S::Future, F>;
40+
type Future = MapErrFuture<S::Future, F>;
3041

42+
#[inline]
3143
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
3244
self.inner.poll_ready(cx).map_err(self.f.clone())
3345
}
3446

47+
#[inline]
3548
fn call(&mut self, request: Request) -> Self::Future {
3649
self.inner.call(request).map_err(self.f.clone())
3750
}
3851
}
3952

40-
/// A [`Layer`] that produces a [`MapErr`] service.
41-
///
42-
/// [`Layer`]: tower_layer::Layer
43-
#[derive(Debug)]
44-
pub struct MapErrLayer<F> {
45-
f: F,
46-
}
47-
4853
impl<F> MapErrLayer<F> {
4954
/// Creates a new [`MapErrLayer`].
5055
pub fn new(f: F) -> Self {

tower/src/util/map_ok.rs

Lines changed: 0 additions & 67 deletions
This file was deleted.

0 commit comments

Comments
 (0)