From bfb37e48c6d345845f4add18f42d476aee789e6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20L=C3=B6thberg?= Date: Thu, 13 Aug 2026 13:54:46 +0200 Subject: [PATCH] feat(aide): implement OperationInput/OperationOutput for axum_extra::either types --- crates/aide/src/axum/inputs.rs | 37 +++++++++++++++++++++++++++++++++ crates/aide/src/axum/outputs.rs | 30 +++++++++++++++++++++++++- 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/crates/aide/src/axum/inputs.rs b/crates/aide/src/axum/inputs.rs index 8da2d4a2..497d28a6 100644 --- a/crates/aide/src/axum/inputs.rs +++ b/crates/aide/src/axum/inputs.rs @@ -451,3 +451,40 @@ where add_parameters(ctx, operation, params); } } + +#[cfg(feature = "axum-extra")] +mod extra { + use axum_extra::either; + + use super::*; + + macro_rules! impl_either { + ($ty:ident, $($e:ident),*) => { + impl<$($e),*> OperationInput for either::$ty<$($e),*> + where + $($e: OperationInput),* + { + fn operation_input(ctx: &mut crate::generate::GenContext, operation: &mut Operation) { + $($e::operation_input(ctx, operation);)* + } + + fn inferred_early_responses( + ctx: &mut crate::generate::GenContext, + operation: &mut Operation, + ) -> Vec<(Option, Response)> { + let mut responses = Vec::new(); + $(responses.extend($e::inferred_early_responses(ctx, operation));)* + responses + } + } + } + } + + impl_either!(Either, E1, E2); + impl_either!(Either3, E1, E2, E3); + impl_either!(Either4, E1, E2, E3, E4); + impl_either!(Either5, E1, E2, E3, E4, E5); + impl_either!(Either6, E1, E2, E3, E4, E5, E6); + impl_either!(Either7, E1, E2, E3, E4, E5, E6, E7); + impl_either!(Either8, E1, E2, E3, E4, E5, E6, E7, E8); +} diff --git a/crates/aide/src/axum/outputs.rs b/crates/aide/src/axum/outputs.rs index 45c9c0f8..e2868686 100644 --- a/crates/aide/src/axum/outputs.rs +++ b/crates/aide/src/axum/outputs.rs @@ -255,7 +255,7 @@ impl OperationOutput for Redirect { #[cfg(feature = "axum-extra")] #[allow(unused_imports)] mod extra { - use axum_extra::{extract, response}; + use axum_extra::{either, extract, response}; use super::*; use crate::{ @@ -266,6 +266,34 @@ mod extra { operation::OperationOutput, }; + macro_rules! impl_either { + ($ty:ident, $($e:ident),*) => { + impl<$($e),*> OperationOutput for either::$ty<$($e),*> + where + $($e: OperationOutput),* + { + type Inner = Self; + + fn inferred_responses( + ctx: &mut GenContext, + operation: &mut Operation, + ) -> Vec<(Option, Response)> { + let mut responses = Vec::new(); + $(responses.extend($e::inferred_responses(ctx, operation));)* + responses + } + } + } + } + + impl_either!(Either, E1, E2); + impl_either!(Either3, E1, E2, E3); + impl_either!(Either4, E1, E2, E3, E4); + impl_either!(Either5, E1, E2, E3, E4, E5); + impl_either!(Either6, E1, E2, E3, E4, E5, E6); + impl_either!(Either7, E1, E2, E3, E4, E5, E6, E7); + impl_either!(Either8, E1, E2, E3, E4, E5, E6, E7, E8); + #[cfg(feature = "axum-extra-cookie")] impl OperationOutput for extract::CookieJar { type Inner = ();