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