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}