diff --git a/tower/Cargo.toml b/tower/Cargo.toml
index 3d5783d72..9a69b6b82 100644
--- a/tower/Cargo.toml
+++ b/tower/Cargo.toml
@@ -63,7 +63,7 @@ retry = ["__common", "tokio/time"]
spawn-ready = ["__common", "futures-util", "tokio/sync", "tokio/rt", "util", "tracing"]
steer = []
timeout = ["pin-project-lite", "tokio/time"]
-util = ["__common", "futures-util", "pin-project"]
+util = ["__common", "futures-util", "pin-project-lite"]
[dependencies]
tower-layer = { version = "0.3.1", path = "../tower-layer" }
@@ -79,7 +79,6 @@ tokio = { version = "1.6", optional = true, features = ["sync"] }
tokio-stream = { version = "0.1.0", optional = true }
tokio-util = { version = "0.7.0", default-features = false, optional = true }
tracing = { version = "0.1.2", default-features = false, features = ["std"], optional = true }
-pin-project = { version = "1", optional = true }
pin-project-lite = { version = "0.2.7", optional = true }
[dev-dependencies]
diff --git a/tower/src/util/either.rs b/tower/src/util/either.rs
index 5933755ef..371abb4d7 100644
--- a/tower/src/util/either.rs
+++ b/tower/src/util/either.rs
@@ -2,8 +2,7 @@
//!
//! See [`Either`] documentation for more details.
-use futures_core::ready;
-use pin_project::pin_project;
+use pin_project_lite::pin_project;
use std::{
future::Future,
pin::Pin,
@@ -17,58 +16,73 @@ use tower_service::Service;
/// Both services must be of the same request, response, and error types.
/// [`Either`] is useful for handling conditional branching in service middleware
/// to different inner service types.
-#[pin_project(project = EitherProj)]
-#[derive(Clone, Debug)]
+#[derive(Clone, Copy, Debug)]
pub enum Either {
- /// One type of backing [`Service`].
- A(#[pin] A),
- /// The other type of backing [`Service`].
- B(#[pin] B),
+ #[allow(missing_docs)]
+ Left(A),
+ #[allow(missing_docs)]
+ Right(B),
}
impl Service for Either
where
A: Service,
- A::Error: Into,
- B: Service,
- B::Error: Into,
+ B: Service,
{
type Response = A::Response;
- type Error = crate::BoxError;
- type Future = Either;
+ type Error = A::Error;
+ type Future = EitherResponseFuture;
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> {
- use self::Either::*;
-
match self {
- A(service) => Poll::Ready(Ok(ready!(service.poll_ready(cx)).map_err(Into::into)?)),
- B(service) => Poll::Ready(Ok(ready!(service.poll_ready(cx)).map_err(Into::into)?)),
+ Either::Left(service) => service.poll_ready(cx),
+ Either::Right(service) => service.poll_ready(cx),
}
}
fn call(&mut self, request: Request) -> Self::Future {
- use self::Either::*;
-
match self {
- A(service) => A(service.call(request)),
- B(service) => B(service.call(request)),
+ Either::Left(service) => EitherResponseFuture {
+ kind: Kind::Left {
+ inner: service.call(request),
+ },
+ },
+ Either::Right(service) => EitherResponseFuture {
+ kind: Kind::Right {
+ inner: service.call(request),
+ },
+ },
}
}
}
-impl Future for Either
+pin_project! {
+ /// Response future for [`Either`].
+ pub struct EitherResponseFuture {
+ #[pin]
+ kind: Kind
+ }
+}
+
+pin_project! {
+ #[project = KindProj]
+ enum Kind {
+ Left { #[pin] inner: A },
+ Right { #[pin] inner: B },
+ }
+}
+
+impl Future for EitherResponseFuture
where
- A: Future