tower_async/util/
either.rs

1//! Contains [`Either`] and related types and functions.
2//!
3//! See [`Either`] documentation for more details.
4
5use tower_async_layer::Layer;
6use tower_async_service::Service;
7
8/// Combine two different service types into a single type.
9///
10/// Both services must be of the same request, response, and error types.
11/// [`Either`] is useful for handling conditional branching in service middleware
12/// to different inner service types.
13#[derive(Clone, Copy, Debug)]
14pub enum Either<A, B> {
15    #[allow(missing_docs)]
16    Left(A),
17    #[allow(missing_docs)]
18    Right(B),
19}
20
21impl<A, B, Request> Service<Request> for Either<A, B>
22where
23    A: Service<Request>,
24    B: Service<Request, Response = A::Response, Error = A::Error>,
25{
26    type Response = A::Response;
27    type Error = A::Error;
28
29    async fn call(&self, request: Request) -> Result<Self::Response, Self::Error> {
30        match self {
31            Either::Left(service) => service.call(request).await,
32            Either::Right(service) => service.call(request).await,
33        }
34    }
35}
36
37impl<S, A, B> Layer<S> for Either<A, B>
38where
39    A: Layer<S>,
40    B: Layer<S>,
41{
42    type Service = Either<A::Service, B::Service>;
43
44    fn layer(&self, inner: S) -> Self::Service {
45        match self {
46            Either::Left(layer) => Either::Left(layer.layer(inner)),
47            Either::Right(layer) => Either::Right(layer.layer(inner)),
48        }
49    }
50}