Coverage Report

Created: 2026-03-11 07:34

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/tower-0.5.2/src/util/either.rs
Line
Count
Source
1
//! Contains [`Either`] and related types and functions.
2
//!
3
//! See [`Either`] documentation for more details.
4
5
use pin_project_lite::pin_project;
6
use std::{
7
    future::Future,
8
    pin::Pin,
9
    task::{Context, Poll},
10
};
11
use tower_layer::Layer;
12
use tower_service::Service;
13
14
/// Combine two different service types into a single type.
15
///
16
/// Both services must be of the same request, response, and error types.
17
/// [`Either`] is useful for handling conditional branching in service middleware
18
/// to different inner service types.
19
#[derive(Clone, Copy, Debug)]
20
pub enum Either<A, B> {
21
    #[allow(missing_docs)]
22
    Left(A),
23
    #[allow(missing_docs)]
24
    Right(B),
25
}
26
27
impl<A, B, Request> Service<Request> for Either<A, B>
28
where
29
    A: Service<Request>,
30
    B: Service<Request, Response = A::Response, Error = A::Error>,
31
{
32
    type Response = A::Response;
33
    type Error = A::Error;
34
    type Future = EitherResponseFuture<A::Future, B::Future>;
35
36
0
    fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
37
0
        match self {
38
0
            Either::Left(service) => service.poll_ready(cx),
39
0
            Either::Right(service) => service.poll_ready(cx),
40
        }
41
0
    }
Unexecuted instantiation: <tower::util::either::Either<tower::limit::concurrency::service::ConcurrencyLimit<tower::util::either::Either<tower::limit::rate::service::RateLimit<tonic::transport::channel::service::reconnect::Reconnect<tonic::transport::channel::service::connection::MakeSendRequestService<tonic::transport::channel::service::connector::Connector<tonic::transport::channel::uds_connector::UdsConnector>>, http::uri::Uri>>, tonic::transport::channel::service::reconnect::Reconnect<tonic::transport::channel::service::connection::MakeSendRequestService<tonic::transport::channel::service::connector::Connector<tonic::transport::channel::uds_connector::UdsConnector>>, http::uri::Uri>>>, tower::util::either::Either<tower::limit::rate::service::RateLimit<tonic::transport::channel::service::reconnect::Reconnect<tonic::transport::channel::service::connection::MakeSendRequestService<tonic::transport::channel::service::connector::Connector<tonic::transport::channel::uds_connector::UdsConnector>>, http::uri::Uri>>, tonic::transport::channel::service::reconnect::Reconnect<tonic::transport::channel::service::connection::MakeSendRequestService<tonic::transport::channel::service::connector::Connector<tonic::transport::channel::uds_connector::UdsConnector>>, http::uri::Uri>>> as tower_service::Service<http::request::Request<tonic::body::Body>>>::poll_ready
Unexecuted instantiation: <tower::util::either::Either<tower::limit::concurrency::service::ConcurrencyLimit<tower::util::either::Either<tower::limit::rate::service::RateLimit<tonic::transport::channel::service::reconnect::Reconnect<tonic::transport::channel::service::connection::MakeSendRequestService<tonic::transport::channel::service::connector::Connector<hyper_util::client::legacy::connect::http::HttpConnector>>, http::uri::Uri>>, tonic::transport::channel::service::reconnect::Reconnect<tonic::transport::channel::service::connection::MakeSendRequestService<tonic::transport::channel::service::connector::Connector<hyper_util::client::legacy::connect::http::HttpConnector>>, http::uri::Uri>>>, tower::util::either::Either<tower::limit::rate::service::RateLimit<tonic::transport::channel::service::reconnect::Reconnect<tonic::transport::channel::service::connection::MakeSendRequestService<tonic::transport::channel::service::connector::Connector<hyper_util::client::legacy::connect::http::HttpConnector>>, http::uri::Uri>>, tonic::transport::channel::service::reconnect::Reconnect<tonic::transport::channel::service::connection::MakeSendRequestService<tonic::transport::channel::service::connector::Connector<hyper_util::client::legacy::connect::http::HttpConnector>>, http::uri::Uri>>> as tower_service::Service<http::request::Request<tonic::body::Body>>>::poll_ready
Unexecuted instantiation: <tower::util::either::Either<tower::limit::rate::service::RateLimit<tonic::transport::channel::service::reconnect::Reconnect<tonic::transport::channel::service::connection::MakeSendRequestService<tonic::transport::channel::service::connector::Connector<tonic::transport::channel::uds_connector::UdsConnector>>, http::uri::Uri>>, tonic::transport::channel::service::reconnect::Reconnect<tonic::transport::channel::service::connection::MakeSendRequestService<tonic::transport::channel::service::connector::Connector<tonic::transport::channel::uds_connector::UdsConnector>>, http::uri::Uri>> as tower_service::Service<http::request::Request<tonic::body::Body>>>::poll_ready
Unexecuted instantiation: <tower::util::either::Either<tower::limit::rate::service::RateLimit<tonic::transport::channel::service::reconnect::Reconnect<tonic::transport::channel::service::connection::MakeSendRequestService<tonic::transport::channel::service::connector::Connector<hyper_util::client::legacy::connect::http::HttpConnector>>, http::uri::Uri>>, tonic::transport::channel::service::reconnect::Reconnect<tonic::transport::channel::service::connection::MakeSendRequestService<tonic::transport::channel::service::connector::Connector<hyper_util::client::legacy::connect::http::HttpConnector>>, http::uri::Uri>> as tower_service::Service<http::request::Request<tonic::body::Body>>>::poll_ready
Unexecuted instantiation: <tower::util::either::Either<_, _> as tower_service::Service<_>>::poll_ready
42
43
0
    fn call(&mut self, request: Request) -> Self::Future {
44
0
        match self {
45
0
            Either::Left(service) => EitherResponseFuture {
46
0
                kind: Kind::Left {
47
0
                    inner: service.call(request),
48
0
                },
49
0
            },
50
0
            Either::Right(service) => EitherResponseFuture {
51
0
                kind: Kind::Right {
52
0
                    inner: service.call(request),
53
0
                },
54
0
            },
55
        }
56
0
    }
Unexecuted instantiation: <tower::util::either::Either<tower::limit::concurrency::service::ConcurrencyLimit<tower::util::either::Either<tower::limit::rate::service::RateLimit<tonic::transport::channel::service::reconnect::Reconnect<tonic::transport::channel::service::connection::MakeSendRequestService<tonic::transport::channel::service::connector::Connector<tonic::transport::channel::uds_connector::UdsConnector>>, http::uri::Uri>>, tonic::transport::channel::service::reconnect::Reconnect<tonic::transport::channel::service::connection::MakeSendRequestService<tonic::transport::channel::service::connector::Connector<tonic::transport::channel::uds_connector::UdsConnector>>, http::uri::Uri>>>, tower::util::either::Either<tower::limit::rate::service::RateLimit<tonic::transport::channel::service::reconnect::Reconnect<tonic::transport::channel::service::connection::MakeSendRequestService<tonic::transport::channel::service::connector::Connector<tonic::transport::channel::uds_connector::UdsConnector>>, http::uri::Uri>>, tonic::transport::channel::service::reconnect::Reconnect<tonic::transport::channel::service::connection::MakeSendRequestService<tonic::transport::channel::service::connector::Connector<tonic::transport::channel::uds_connector::UdsConnector>>, http::uri::Uri>>> as tower_service::Service<http::request::Request<tonic::body::Body>>>::call
Unexecuted instantiation: <tower::util::either::Either<tower::limit::concurrency::service::ConcurrencyLimit<tower::util::either::Either<tower::limit::rate::service::RateLimit<tonic::transport::channel::service::reconnect::Reconnect<tonic::transport::channel::service::connection::MakeSendRequestService<tonic::transport::channel::service::connector::Connector<hyper_util::client::legacy::connect::http::HttpConnector>>, http::uri::Uri>>, tonic::transport::channel::service::reconnect::Reconnect<tonic::transport::channel::service::connection::MakeSendRequestService<tonic::transport::channel::service::connector::Connector<hyper_util::client::legacy::connect::http::HttpConnector>>, http::uri::Uri>>>, tower::util::either::Either<tower::limit::rate::service::RateLimit<tonic::transport::channel::service::reconnect::Reconnect<tonic::transport::channel::service::connection::MakeSendRequestService<tonic::transport::channel::service::connector::Connector<hyper_util::client::legacy::connect::http::HttpConnector>>, http::uri::Uri>>, tonic::transport::channel::service::reconnect::Reconnect<tonic::transport::channel::service::connection::MakeSendRequestService<tonic::transport::channel::service::connector::Connector<hyper_util::client::legacy::connect::http::HttpConnector>>, http::uri::Uri>>> as tower_service::Service<http::request::Request<tonic::body::Body>>>::call
Unexecuted instantiation: <tower::util::either::Either<tower::limit::rate::service::RateLimit<tonic::transport::channel::service::reconnect::Reconnect<tonic::transport::channel::service::connection::MakeSendRequestService<tonic::transport::channel::service::connector::Connector<tonic::transport::channel::uds_connector::UdsConnector>>, http::uri::Uri>>, tonic::transport::channel::service::reconnect::Reconnect<tonic::transport::channel::service::connection::MakeSendRequestService<tonic::transport::channel::service::connector::Connector<tonic::transport::channel::uds_connector::UdsConnector>>, http::uri::Uri>> as tower_service::Service<http::request::Request<tonic::body::Body>>>::call
Unexecuted instantiation: <tower::util::either::Either<tower::limit::rate::service::RateLimit<tonic::transport::channel::service::reconnect::Reconnect<tonic::transport::channel::service::connection::MakeSendRequestService<tonic::transport::channel::service::connector::Connector<hyper_util::client::legacy::connect::http::HttpConnector>>, http::uri::Uri>>, tonic::transport::channel::service::reconnect::Reconnect<tonic::transport::channel::service::connection::MakeSendRequestService<tonic::transport::channel::service::connector::Connector<hyper_util::client::legacy::connect::http::HttpConnector>>, http::uri::Uri>> as tower_service::Service<http::request::Request<tonic::body::Body>>>::call
Unexecuted instantiation: <tower::util::either::Either<_, _> as tower_service::Service<_>>::call
57
}
58
59
pin_project! {
60
    /// Response future for [`Either`].
61
    pub struct EitherResponseFuture<A, B> {
62
        #[pin]
63
        kind: Kind<A, B>
64
    }
65
}
66
67
pin_project! {
68
    #[project = KindProj]
69
    enum Kind<A, B> {
70
        Left { #[pin] inner: A },
71
        Right { #[pin] inner: B },
72
    }
73
}
74
75
impl<A, B> Future for EitherResponseFuture<A, B>
76
where
77
    A: Future,
78
    B: Future<Output = A::Output>,
79
{
80
    type Output = A::Output;
81
82
0
    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
83
0
        match self.project().kind.project() {
84
0
            KindProj::Left { inner } => inner.poll(cx),
85
0
            KindProj::Right { inner } => inner.poll(cx),
86
        }
87
0
    }
Unexecuted instantiation: <tower::util::either::EitherResponseFuture<tower::limit::concurrency::future::ResponseFuture<tower::util::either::EitherResponseFuture<tonic::transport::channel::service::reconnect::ResponseFuture<core::pin::Pin<alloc::boxed::Box<dyn core::future::future::Future<Output = core::result::Result<http::response::Response<tonic::body::Body>, alloc::boxed::Box<dyn core::error::Error + core::marker::Send + core::marker::Sync>>> + core::marker::Send>>>, tonic::transport::channel::service::reconnect::ResponseFuture<core::pin::Pin<alloc::boxed::Box<dyn core::future::future::Future<Output = core::result::Result<http::response::Response<tonic::body::Body>, alloc::boxed::Box<dyn core::error::Error + core::marker::Send + core::marker::Sync>>> + core::marker::Send>>>>>, tower::util::either::EitherResponseFuture<tonic::transport::channel::service::reconnect::ResponseFuture<core::pin::Pin<alloc::boxed::Box<dyn core::future::future::Future<Output = core::result::Result<http::response::Response<tonic::body::Body>, alloc::boxed::Box<dyn core::error::Error + core::marker::Send + core::marker::Sync>>> + core::marker::Send>>>, tonic::transport::channel::service::reconnect::ResponseFuture<core::pin::Pin<alloc::boxed::Box<dyn core::future::future::Future<Output = core::result::Result<http::response::Response<tonic::body::Body>, alloc::boxed::Box<dyn core::error::Error + core::marker::Send + core::marker::Sync>>> + core::marker::Send>>>>> as core::future::future::Future>::poll
Unexecuted instantiation: <tower::util::either::EitherResponseFuture<tonic::transport::channel::service::reconnect::ResponseFuture<core::pin::Pin<alloc::boxed::Box<dyn core::future::future::Future<Output = core::result::Result<http::response::Response<tonic::body::Body>, alloc::boxed::Box<dyn core::error::Error + core::marker::Send + core::marker::Sync>>> + core::marker::Send>>>, tonic::transport::channel::service::reconnect::ResponseFuture<core::pin::Pin<alloc::boxed::Box<dyn core::future::future::Future<Output = core::result::Result<http::response::Response<tonic::body::Body>, alloc::boxed::Box<dyn core::error::Error + core::marker::Send + core::marker::Sync>>> + core::marker::Send>>>> as core::future::future::Future>::poll
Unexecuted instantiation: <tower::util::either::EitherResponseFuture<_, _> as core::future::future::Future>::poll
88
}
89
90
impl<S, A, B> Layer<S> for Either<A, B>
91
where
92
    A: Layer<S>,
93
    B: Layer<S>,
94
{
95
    type Service = Either<A::Service, B::Service>;
96
97
0
    fn layer(&self, inner: S) -> Self::Service {
98
0
        match self {
99
0
            Either::Left(layer) => Either::Left(layer.layer(inner)),
100
0
            Either::Right(layer) => Either::Right(layer.layer(inner)),
101
        }
102
0
    }
Unexecuted instantiation: <tower::util::either::Either<tower::limit::concurrency::layer::ConcurrencyLimitLayer, tower_layer::identity::Identity> as tower_layer::Layer<tower::util::either::Either<tower::limit::rate::service::RateLimit<tonic::transport::channel::service::reconnect::Reconnect<tonic::transport::channel::service::connection::MakeSendRequestService<tonic::transport::channel::service::connector::Connector<tonic::transport::channel::uds_connector::UdsConnector>>, http::uri::Uri>>, tonic::transport::channel::service::reconnect::Reconnect<tonic::transport::channel::service::connection::MakeSendRequestService<tonic::transport::channel::service::connector::Connector<tonic::transport::channel::uds_connector::UdsConnector>>, http::uri::Uri>>>>::layer
Unexecuted instantiation: <tower::util::either::Either<tower::limit::concurrency::layer::ConcurrencyLimitLayer, tower_layer::identity::Identity> as tower_layer::Layer<tower::util::either::Either<tower::limit::rate::service::RateLimit<tonic::transport::channel::service::reconnect::Reconnect<tonic::transport::channel::service::connection::MakeSendRequestService<tonic::transport::channel::service::connector::Connector<hyper_util::client::legacy::connect::http::HttpConnector>>, http::uri::Uri>>, tonic::transport::channel::service::reconnect::Reconnect<tonic::transport::channel::service::connection::MakeSendRequestService<tonic::transport::channel::service::connector::Connector<hyper_util::client::legacy::connect::http::HttpConnector>>, http::uri::Uri>>>>::layer
Unexecuted instantiation: <tower::util::either::Either<tower::limit::rate::layer::RateLimitLayer, tower_layer::identity::Identity> as tower_layer::Layer<tonic::transport::channel::service::reconnect::Reconnect<tonic::transport::channel::service::connection::MakeSendRequestService<tonic::transport::channel::service::connector::Connector<tonic::transport::channel::uds_connector::UdsConnector>>, http::uri::Uri>>>::layer
Unexecuted instantiation: <tower::util::either::Either<tower::limit::rate::layer::RateLimitLayer, tower_layer::identity::Identity> as tower_layer::Layer<tonic::transport::channel::service::reconnect::Reconnect<tonic::transport::channel::service::connection::MakeSendRequestService<tonic::transport::channel::service::connector::Connector<hyper_util::client::legacy::connect::http::HttpConnector>>, http::uri::Uri>>>::layer
Unexecuted instantiation: <tower::util::either::Either<_, _> as tower_layer::Layer<_>>::layer
103
}