aws_smithy_http_server/plugin/
either.rs1use pin_project_lite::pin_project;
9use std::{
10    future::Future,
11    pin::Pin,
12    task::{Context, Poll},
13};
14use tower::{Layer, Service};
15
16use super::Plugin;
17
18pin_project! {
21    #[derive(Clone, Debug)]
32    #[project = EitherProj]
33    pub enum Either<L, R> {
34        Left { #[pin] value: L },
36        Right { #[pin] value: R },
38    }
39}
40
41impl<L, R> Future for Either<L, R>
42where
43    L: Future,
44    R: Future<Output = L::Output>,
45{
46    type Output = L::Output;
47
48    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
49        match self.project() {
50            EitherProj::Left { value } => value.poll(cx),
51            EitherProj::Right { value } => value.poll(cx),
52        }
53    }
54}
55
56impl<L, R, Request> Service<Request> for Either<L, R>
57where
58    L: Service<Request>,
59    R: Service<Request, Response = L::Response, Error = L::Error>,
60{
61    type Response = L::Response;
62    type Error = L::Error;
63    type Future = Either<L::Future, R::Future>;
64
65    fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
66        use self::Either::*;
67
68        match self {
69            Left { value } => value.poll_ready(cx),
70            Right { value } => value.poll_ready(cx),
71        }
72    }
73
74    fn call(&mut self, request: Request) -> Self::Future {
75        use self::Either::*;
76
77        match self {
78            Left { value } => Either::Left {
79                value: value.call(request),
80            },
81            Right { value } => Either::Right {
82                value: value.call(request),
83            },
84        }
85    }
86}
87
88impl<S, L, R> Layer<S> for Either<L, R>
89where
90    L: Layer<S>,
91    R: Layer<S>,
92{
93    type Service = Either<L::Service, R::Service>;
94
95    fn layer(&self, inner: S) -> Self::Service {
96        match self {
97            Either::Left { value } => Either::Left {
98                value: value.layer(inner),
99            },
100            Either::Right { value } => Either::Right {
101                value: value.layer(inner),
102            },
103        }
104    }
105}
106
107impl<Ser, Op, T, Le, Ri> Plugin<Ser, Op, T> for Either<Le, Ri>
108where
109    Le: Plugin<Ser, Op, T>,
110    Ri: Plugin<Ser, Op, T>,
111{
112    type Output = Either<Le::Output, Ri::Output>;
113
114    fn apply(&self, input: T) -> Self::Output {
115        match self {
116            Either::Left { value } => Either::Left {
117                value: value.apply(input),
118            },
119            Either::Right { value } => Either::Right {
120                value: value.apply(input),
121            },
122        }
123    }
124}