1use std::convert::Infallible;
2
3use axum::routing;
4
5use crate::{
6 handler::{CodecHandlerFn, Input},
7 CodecHandler, IntoCodecResponse,
8};
9
10pub struct MethodRouter<S = (), E = Infallible> {
18 #[cfg(not(feature = "aide"))]
19 inner: routing::MethodRouter<S, E>,
20 #[cfg(feature = "aide")]
21 inner: aide::axum::routing::ApiMethodRouter<S, E>,
22}
23
24impl<S, E> Clone for MethodRouter<S, E> {
25 fn clone(&self) -> Self {
26 Self {
27 inner: self.inner.clone(),
28 }
29 }
30}
31
32#[cfg(not(feature = "aide"))]
33impl<S, E> From<MethodRouter<S, E>> for routing::MethodRouter<S, E> {
34 fn from(router: MethodRouter<S, E>) -> Self {
35 router.inner
36 }
37}
38
39#[cfg(not(feature = "aide"))]
40impl<S, E> From<routing::MethodRouter<S, E>> for MethodRouter<S, E> {
41 fn from(router: routing::MethodRouter<S, E>) -> Self {
42 Self { inner: router }
43 }
44}
45
46#[cfg(feature = "aide")]
47impl<S, E> From<routing::MethodRouter<S, E>> for MethodRouter<S, E> {
48 fn from(router: routing::MethodRouter<S, E>) -> Self {
49 Self {
50 inner: router.into(),
51 }
52 }
53}
54
55#[cfg(feature = "aide")]
56impl<S, E> From<MethodRouter<S, E>> for routing::MethodRouter<S, E> {
57 fn from(router: MethodRouter<S, E>) -> Self {
58 router.inner.into()
59 }
60}
61
62#[cfg(feature = "aide")]
63impl<S, E> From<aide::axum::routing::ApiMethodRouter<S, E>> for MethodRouter<S, E> {
64 fn from(router: aide::axum::routing::ApiMethodRouter<S, E>) -> Self {
65 Self { inner: router }
66 }
67}
68
69#[cfg(feature = "aide")]
70impl<S, E> From<MethodRouter<S, E>> for aide::axum::routing::ApiMethodRouter<S, E> {
71 fn from(router: MethodRouter<S, E>) -> Self {
72 router.inner
73 }
74}
75
76#[cfg(not(feature = "aide"))]
77macro_rules! method_router_chain_method {
78 ($name:ident, $with:ident) => {
79 #[doc = concat!("Route `", stringify!($name) ,"` requests to the given handler. See [`axum::routing::MethodRouter::", stringify!($name) , "`] for more details.")]
80 #[must_use]
81 pub fn $name<T, H, I, D>(mut self, handler: H) -> Self
82 where
83 H: CodecHandler<T, I, D, S> + Clone + Send + Sync + 'static,
84 I: Input + Send + Sync + 'static,
85 D: IntoCodecResponse + Send + 'static,
86 S: Clone + Send + Sync + 'static,
87 T: Sync + 'static
88 {
89 self.inner = self.inner.$name(CodecHandlerFn::new(handler));
90 self
91 }
92 };
93}
94
95#[cfg(feature = "aide")]
96macro_rules! method_router_chain_method {
97 ($name:ident, $with:ident) => {
98 #[doc = concat!("Route `", stringify!($name) ,"` requests to the given handler. See [`axum::routing::MethodRouter::", stringify!($name) , "`] for more details.")]
99 #[must_use]
100 pub fn $name<T, H, I, D>(mut self, handler: H) -> Self
101 where
102 H: CodecHandler<T, I, D, S> + Clone + Send + Sync + 'static,
103 I: Input + Send + Sync + 'static,
104 D: IntoCodecResponse + Send + 'static,
105 S: Clone + Send + Sync + 'static,
106 T: Sync + 'static,
107 {
108 self.inner = self.inner.$name(CodecHandlerFn::<H, I, D>::new(handler));
109 self
110 }
111
112 #[doc = concat!("Route `", stringify!($name) ,"` requests to the given handler. See [`axum::routing::MethodRouter::", stringify!($name) , "`] for more details.")]
113 #[must_use]
114 pub fn $with<T, H, I, D, F>(mut self, handler: H, transform: F) -> Self
115 where
116 H: CodecHandler<T, I, D, S> + Clone + Send + Sync + 'static,
117 I: Input + Send + Sync + 'static,
118 D: IntoCodecResponse + Send + 'static,
119 S: Clone + Send + Sync + 'static,
120 T: Sync + 'static,
121 F: FnOnce(aide::transform::TransformOperation) -> aide::transform::TransformOperation,
122 {
123 self.inner = self.inner.$with(CodecHandlerFn::<H, I, D>::new(handler), transform);
124 self
125 }
126 };
127}
128
129impl<S> MethodRouter<S, Infallible>
130where
131 S: Clone + Send + Sync + 'static,
132{
133 method_router_chain_method!(delete, delete_with);
134
135 method_router_chain_method!(get, get_with);
136
137 method_router_chain_method!(head, head_with);
138
139 method_router_chain_method!(options, options_with);
140
141 method_router_chain_method!(patch, patch_with);
142
143 method_router_chain_method!(post, post_with);
144
145 method_router_chain_method!(put, put_with);
146
147 method_router_chain_method!(trace, trace_with);
148}
149
150#[cfg(not(feature = "aide"))]
151macro_rules! method_router_top_level {
152 ($name:ident, $with:ident) => {
153 #[doc = concat!("Route `", stringify!($name) ,"` requests to the given handler. See [`axum::routing::", stringify!($name) , "`] for more details.")]
154 pub fn $name<T, H, I, D, S>(handler: H) -> MethodRouter<S, Infallible>
155 where
156 H: CodecHandler<T, I, D, S> + Clone + Send + Sync + 'static,
157 I: Input + Send + Sync + 'static,
158 D: IntoCodecResponse + Send + 'static,
159 S: Clone + Send + Sync + 'static,
160 T: Sync + 'static
161 {
162 MethodRouter::from(routing::$name(CodecHandlerFn::new(handler)))
163 }
164 };
165}
166
167#[cfg(feature = "aide")]
168macro_rules! method_router_top_level {
169 ($name:ident, $with:ident) => {
170 #[doc = concat!("Route `", stringify!($name) ,"` requests to the given handler. See [`axum::routing::", stringify!($name) , "`] for more details.")]
171 pub fn $name<T, H, I, D, S>(handler: H) -> MethodRouter<S, Infallible>
172 where
173 H: CodecHandler<T, I, D, S> + Clone + Send + Sync + 'static,
174 I: Input + Send + Sync + 'static,
175 D: IntoCodecResponse + Send + 'static,
176 S: Clone + Send + Sync + 'static,
177 T: Sync + 'static,
178 {
179 MethodRouter::from(aide::axum::routing::$name(
180 CodecHandlerFn::<H, I, D>::new(handler),
181 ))
182 }
183
184 #[doc = concat!("Route `", stringify!($name) ,"` requests to the given handler. See [`axum::routing::", stringify!($name) , "`] for more details.")]
185 #[must_use]
186 pub fn $with<T, H, I, D, S, F>(handler: H, transform: F) -> MethodRouter<S, Infallible>
187 where
188 H: CodecHandler<T, I, D, S> + Clone + Send + Sync + 'static,
189 I: Input + Send + Sync + 'static,
190 D: IntoCodecResponse + Send + 'static,
191 S: Clone + Send + Sync + 'static,
192 T: Sync + 'static,
193 F: FnOnce(aide::transform::TransformOperation) -> aide::transform::TransformOperation,
194 {
195 MethodRouter::from(aide::axum::routing::$with(CodecHandlerFn::<H, I, D>::new(handler), transform))
196 }
197 };
198}
199
200method_router_top_level!(delete, delete_with);
201method_router_top_level!(get, get_with);
202method_router_top_level!(head, head_with);
203method_router_top_level!(options, options_with);
204method_router_top_level!(patch, patch_with);
205method_router_top_level!(post, post_with);
206method_router_top_level!(put, put_with);
207method_router_top_level!(trace, trace_with);