1use std::{error::Error, fmt::Display, future::Future, pin::Pin};
2
3use crate::{layer::FactoryLayer, AsyncMakeService, MakeService, Service};
4
5#[derive(Debug, Clone)]
37pub enum Either<A, B> {
38 Left(A),
39 Right(B),
40}
41
42impl<C, F, T> FactoryLayer<C, F> for Option<T>
43where
44 T: FactoryLayer<C, F>,
45{
46 type Factory = Either<T::Factory, F>;
47
48 #[inline]
49 fn layer(&self, config: &C, inner: F) -> Self::Factory {
50 match self {
51 Some(fl) => Either::Left(fl.layer(config, inner)),
52 None => Either::Right(inner),
53 }
54 }
55}
56
57impl<C, F, FLA, FLB> FactoryLayer<C, F> for Either<FLA, FLB>
58where
59 FLA: FactoryLayer<C, F>,
60 FLB: FactoryLayer<C, F>,
61{
62 type Factory = Either<FLA::Factory, FLB::Factory>;
63
64 #[inline]
65 fn layer(&self, config: &C, inner: F) -> Self::Factory {
66 match self {
67 Either::Left(fl) => Either::Left(fl.layer(config, inner)),
68 Either::Right(fl) => Either::Right(fl.layer(config, inner)),
69 }
70 }
71}
72
73impl<A, B> MakeService for Either<A, B>
74where
75 A: MakeService,
76 B: MakeService,
77{
78 type Service = Either<A::Service, B::Service>;
79 type Error = Either<A::Error, B::Error>;
80
81 fn make_via_ref(&self, old: Option<&Self::Service>) -> Result<Self::Service, Self::Error> {
82 match self {
83 Either::Left(f) => match old.as_ref() {
84 Some(Either::Left(left_svc)) => f.make_via_ref(Some(left_svc)),
85 _ => f.make(),
86 }
87 .map(Either::Left)
88 .map_err(Either::Left),
89 Either::Right(f) => match old.as_ref() {
90 Some(Either::Right(right_svc)) => f.make_via_ref(Some(right_svc)),
91 _ => f.make(),
92 }
93 .map(Either::Right)
94 .map_err(Either::Right),
95 }
96 }
97}
98
99impl<A, B> AsyncMakeService for Either<A, B>
100where
101 A: AsyncMakeService,
102 B: AsyncMakeService,
103{
104 type Service = Either<A::Service, B::Service>;
105 type Error = Either<A::Error, B::Error>;
106
107 async fn make_via_ref(
108 &self,
109 old: Option<&Self::Service>,
110 ) -> Result<Self::Service, Self::Error> {
111 match self {
112 Either::Left(f) => match old.as_ref() {
113 Some(Either::Left(left_svc)) => f.make_via_ref(Some(left_svc)).await,
114 _ => f.make().await,
115 }
116 .map(Either::Left)
117 .map_err(Either::Left),
118 Either::Right(f) => match old.as_ref() {
119 Some(Either::Right(right_svc)) => f.make_via_ref(Some(right_svc)).await,
120 _ => f.make().await,
121 }
122 .map(Either::Right)
123 .map_err(Either::Right),
124 }
125 }
126}
127
128impl<A, B, R> Service<R> for Either<A, B>
129where
130 A: Service<R>,
131 B: Service<R, Response = A::Response, Error = A::Error>,
132{
133 type Response = A::Response;
134 type Error = A::Error;
135
136 #[inline]
137 fn call(&self, req: R) -> impl Future<Output = Result<Self::Response, Self::Error>> {
138 match self {
139 Either::Left(s) => Either::Left(s.call(req)),
140 Either::Right(s) => Either::Right(s.call(req)),
141 }
142 }
143}
144
145impl<A, B> Future for Either<A, B>
146where
147 A: Future,
148 B: Future<Output = A::Output>,
149{
150 type Output = A::Output;
151
152 #[inline]
153 fn poll(
154 self: std::pin::Pin<&mut Self>,
155 cx: &mut std::task::Context<'_>,
156 ) -> std::task::Poll<Self::Output> {
157 match self.as_pin_mut() {
158 Either::Left(fut) => fut.poll(cx),
159 Either::Right(fut) => fut.poll(cx),
160 }
161 }
162}
163
164impl<A, B> Either<A, B> {
166 #[inline]
169 pub fn as_pin_ref(self: Pin<&Self>) -> Either<Pin<&A>, Pin<&B>> {
170 unsafe {
173 match *Pin::get_ref(self) {
174 Either::Left(ref inner) => Either::Left(Pin::new_unchecked(inner)),
175 Either::Right(ref inner) => Either::Right(Pin::new_unchecked(inner)),
176 }
177 }
178 }
179
180 #[inline]
183 pub fn as_pin_mut(self: Pin<&mut Self>) -> Either<Pin<&mut A>, Pin<&mut B>> {
184 unsafe {
190 match *Pin::get_unchecked_mut(self) {
191 Either::Left(ref mut inner) => Either::Left(Pin::new_unchecked(inner)),
192 Either::Right(ref mut inner) => Either::Right(Pin::new_unchecked(inner)),
193 }
194 }
195 }
196}
197
198impl<A: Display, B: Display> Display for Either<A, B> {
199 #[inline]
200 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
201 match self {
202 Either::Left(inner) => inner.fmt(f),
203 Either::Right(inner) => inner.fmt(f),
204 }
205 }
206}
207
208impl<A: Error, B: Error> Error for Either<A, B> {
209 fn source(&self) -> Option<&(dyn Error + 'static)> {
210 match self {
211 Either::Left(inner) => inner.source(),
212 Either::Right(inner) => inner.source(),
213 }
214 }
215}
216
217impl<T> Either<T, T> {
218 #[inline]
219 pub fn into_inner(self) -> T {
220 match self {
221 Either::Left(t) => t,
222 Either::Right(t) => t,
223 }
224 }
225}