1use std::task::{Context, Poll};
94
95use axum::{
96 extract::FromRequestParts,
97 response::{IntoResponse, Response},
98};
99use http::request::Parts;
100use tower_layer::Layer;
101use tower_service::Service;
102
103#[derive(Debug, Clone)]
107#[must_use]
108pub enum Either<E1, E2> {
109 #[allow(missing_docs)]
110 E1(E1),
111 #[allow(missing_docs)]
112 E2(E2),
113}
114
115#[derive(Debug, Clone)]
119#[must_use]
120pub enum Either3<E1, E2, E3> {
121 #[allow(missing_docs)]
122 E1(E1),
123 #[allow(missing_docs)]
124 E2(E2),
125 #[allow(missing_docs)]
126 E3(E3),
127}
128
129#[derive(Debug, Clone)]
133#[must_use]
134pub enum Either4<E1, E2, E3, E4> {
135 #[allow(missing_docs)]
136 E1(E1),
137 #[allow(missing_docs)]
138 E2(E2),
139 #[allow(missing_docs)]
140 E3(E3),
141 #[allow(missing_docs)]
142 E4(E4),
143}
144
145#[derive(Debug, Clone)]
149#[must_use]
150pub enum Either5<E1, E2, E3, E4, E5> {
151 #[allow(missing_docs)]
152 E1(E1),
153 #[allow(missing_docs)]
154 E2(E2),
155 #[allow(missing_docs)]
156 E3(E3),
157 #[allow(missing_docs)]
158 E4(E4),
159 #[allow(missing_docs)]
160 E5(E5),
161}
162
163#[derive(Debug, Clone)]
167#[must_use]
168pub enum Either6<E1, E2, E3, E4, E5, E6> {
169 #[allow(missing_docs)]
170 E1(E1),
171 #[allow(missing_docs)]
172 E2(E2),
173 #[allow(missing_docs)]
174 E3(E3),
175 #[allow(missing_docs)]
176 E4(E4),
177 #[allow(missing_docs)]
178 E5(E5),
179 #[allow(missing_docs)]
180 E6(E6),
181}
182
183#[derive(Debug, Clone)]
187#[must_use]
188pub enum Either7<E1, E2, E3, E4, E5, E6, E7> {
189 #[allow(missing_docs)]
190 E1(E1),
191 #[allow(missing_docs)]
192 E2(E2),
193 #[allow(missing_docs)]
194 E3(E3),
195 #[allow(missing_docs)]
196 E4(E4),
197 #[allow(missing_docs)]
198 E5(E5),
199 #[allow(missing_docs)]
200 E6(E6),
201 #[allow(missing_docs)]
202 E7(E7),
203}
204
205#[derive(Debug, Clone)]
209#[must_use]
210pub enum Either8<E1, E2, E3, E4, E5, E6, E7, E8> {
211 #[allow(missing_docs)]
212 E1(E1),
213 #[allow(missing_docs)]
214 E2(E2),
215 #[allow(missing_docs)]
216 E3(E3),
217 #[allow(missing_docs)]
218 E4(E4),
219 #[allow(missing_docs)]
220 E5(E5),
221 #[allow(missing_docs)]
222 E6(E6),
223 #[allow(missing_docs)]
224 E7(E7),
225 #[allow(missing_docs)]
226 E8(E8),
227}
228
229macro_rules! impl_traits_for_either {
230 (
231 $either:ident =>
232 [$($ident:ident),* $(,)?],
233 $last:ident $(,)?
234 ) => {
235 impl<S, $($ident),*, $last> FromRequestParts<S> for $either<$($ident),*, $last>
236 where
237 $($ident: FromRequestParts<S>),*,
238 $last: FromRequestParts<S>,
239 S: Send + Sync,
240 {
241 type Rejection = $last::Rejection;
242
243 async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {
244 $(
245 if let Ok(value) = <$ident as FromRequestParts<S>>::from_request_parts(parts, state).await {
246 return Ok(Self::$ident(value));
247 }
248 )*
249
250 <$last as FromRequestParts<S>>::from_request_parts(parts, state).await.map(Self::$last)
251 }
252 }
253
254 impl<$($ident),*, $last> IntoResponse for $either<$($ident),*, $last>
255 where
256 $($ident: IntoResponse),*,
257 $last: IntoResponse,
258 {
259 fn into_response(self) -> Response {
260 match self {
261 $( Self::$ident(value) => value.into_response(), )*
262 Self::$last(value) => value.into_response(),
263 }
264 }
265 }
266 };
267}
268
269impl_traits_for_either!(Either => [E1], E2);
270impl_traits_for_either!(Either3 => [E1, E2], E3);
271impl_traits_for_either!(Either4 => [E1, E2, E3], E4);
272impl_traits_for_either!(Either5 => [E1, E2, E3, E4], E5);
273impl_traits_for_either!(Either6 => [E1, E2, E3, E4, E5], E6);
274impl_traits_for_either!(Either7 => [E1, E2, E3, E4, E5, E6], E7);
275impl_traits_for_either!(Either8 => [E1, E2, E3, E4, E5, E6, E7], E8);
276
277impl<E1, E2, S> Layer<S> for Either<E1, E2>
278where
279 E1: Layer<S>,
280 E2: Layer<S>,
281{
282 type Service = Either<E1::Service, E2::Service>;
283
284 fn layer(&self, inner: S) -> Self::Service {
285 match self {
286 Either::E1(layer) => Either::E1(layer.layer(inner)),
287 Either::E2(layer) => Either::E2(layer.layer(inner)),
288 }
289 }
290}
291
292impl<R, E1, E2> Service<R> for Either<E1, E2>
293where
294 E1: Service<R>,
295 E2: Service<R, Response = E1::Response, Error = E1::Error>,
296{
297 type Response = E1::Response;
298 type Error = E1::Error;
299 type Future = futures_util::future::Either<E1::Future, E2::Future>;
300
301 fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
302 match self {
303 Either::E1(inner) => inner.poll_ready(cx),
304 Either::E2(inner) => inner.poll_ready(cx),
305 }
306 }
307
308 fn call(&mut self, req: R) -> Self::Future {
309 match self {
310 Either::E1(inner) => futures_util::future::Either::Left(inner.call(req)),
311 Either::E2(inner) => futures_util::future::Either::Right(inner.call(req)),
312 }
313 }
314}