1use core::fmt;
12use std::collections::HashSet;
13
14use super::collection::RouteCollection;
15use crate::state;
16
17pub struct Router<UserState> {
22 pub name: String,
23 pub fullpath: String,
24 pub methods: HashSet<axum::http::Method>,
25 pub action: Option<axum::routing::MethodRouter<state::State<UserState>>>,
26}
27
28impl<US> Router<US> {
33 pub fn path(path: impl ToString + fmt::Debug) -> Self {
34 let name = format!("{path:?}");
35 Self {
36 name,
37 fullpath: path.to_string(),
38 action: Default::default(),
39 methods: Default::default(),
40 }
41 }
42
43 pub fn any<Action, ActionType>(mut self, action: Action) -> Self
44 where
45 Action: axum::handler::Handler<ActionType, state::State<US>>,
46 ActionType: 'static,
47 US: 'static,
48 US: Clone,
49 US: Send + Sync,
50 {
51 self.action.replace(axum::routing::any(action));
52 self.methods.extend([
53 axum::http::Method::DELETE,
54 axum::http::Method::GET,
55 axum::http::Method::HEAD,
56 axum::http::Method::OPTIONS,
57 axum::http::Method::PATCH,
58 axum::http::Method::POST,
59 axum::http::Method::PUT,
60 axum::http::Method::TRACE,
61 ]);
62 self
63 }
64
65 pub fn delete<Action, ActionType>(mut self, action: Action) -> Self
66 where
67 Action: axum::handler::Handler<ActionType, state::State<US>>,
68 ActionType: 'static,
69 US: 'static,
70 US: Clone,
71 US: Send + Sync,
72 {
73 if let Some(current_action) = self.action.take() {
74 self.action.replace(current_action.delete(action));
75 } else {
76 self.action.replace(axum::routing::delete(action));
77 }
78 self.methods.insert(axum::http::Method::DELETE);
79 self
80 }
81
82 pub fn get<Action, ActionType>(mut self, action: Action) -> Self
83 where
84 Action: axum::handler::Handler<ActionType, state::State<US>>,
85 ActionType: 'static,
86 US: 'static,
87 US: Clone,
88 US: Send + Sync,
89 {
90 if let Some(current_action) = self.action.take() {
91 self.action.replace(current_action.get(action));
92 } else {
93 self.action.replace(axum::routing::get(action));
94 }
95 self.methods.insert(axum::http::Method::GET);
96 self
97 }
98
99 pub fn head<Action, ActionType>(mut self, action: Action) -> Self
100 where
101 Action: axum::handler::Handler<ActionType, state::State<US>>,
102 ActionType: 'static,
103 US: 'static,
104 US: Clone,
105 US: Send + Sync,
106 {
107 if let Some(current_action) = self.action.take() {
108 self.action.replace(current_action.head(action));
109 } else {
110 self.action.replace(axum::routing::head(action));
111 }
112 self.methods.insert(axum::http::Method::HEAD);
113 self
114 }
115
116 pub fn options<Action, ActionType>(mut self, action: Action) -> Self
117 where
118 Action: axum::handler::Handler<ActionType, state::State<US>>,
119 ActionType: 'static,
120 US: 'static,
121 US: Clone,
122 US: Send + Sync,
123 {
124 if let Some(current_action) = self.action.take() {
125 self.action.replace(current_action.options(action));
126 } else {
127 self.action.replace(axum::routing::options(action));
128 }
129 self.methods.insert(axum::http::Method::OPTIONS);
130 self
131 }
132
133 pub fn patch<Action, ActionType>(mut self, action: Action) -> Self
134 where
135 Action: axum::handler::Handler<ActionType, state::State<US>>,
136 ActionType: 'static,
137 US: 'static,
138 US: Clone,
139 US: Send + Sync,
140 {
141 if let Some(current_action) = self.action.take() {
142 self.action.replace(current_action.patch(action));
143 } else {
144 self.action.replace(axum::routing::patch(action));
145 }
146 self.methods.insert(axum::http::Method::PATCH);
147 self
148 }
149
150 pub fn post<Action, ActionType>(mut self, action: Action) -> Self
151 where
152 Action: axum::handler::Handler<ActionType, state::State<US>>,
153 ActionType: 'static,
154 US: 'static,
155 US: Clone,
156 US: Send + Sync,
157 {
158 if let Some(current_action) = self.action.take() {
159 self.action.replace(current_action.post(action));
160 } else {
161 self.action.replace(axum::routing::post(action));
162 }
163 self.methods.insert(axum::http::Method::POST);
164 self
165 }
166
167 pub fn put<Action, ActionType>(mut self, action: Action) -> Self
168 where
169 Action: axum::handler::Handler<ActionType, state::State<US>>,
170 ActionType: 'static,
171 US: 'static,
172 US: Clone,
173 US: Send + Sync,
174 {
175 if let Some(current_action) = self.action.take() {
176 self.action.replace(current_action.put(action));
177 } else {
178 self.action.replace(axum::routing::put(action));
179 }
180 self.methods.insert(axum::http::Method::PUT);
181 self
182 }
183
184 pub fn trace<Action, ActionType>(mut self, action: Action) -> Self
185 where
186 Action: axum::handler::Handler<ActionType, state::State<US>>,
187 ActionType: 'static,
188 US: 'static,
189 US: Clone,
190 US: Send + Sync,
191 {
192 if let Some(current_action) = self.action.take() {
193 self.action.replace(current_action.trace(action));
194 } else {
195 self.action.replace(axum::routing::trace(action));
196 }
197 self.methods.insert(axum::http::Method::TRACE);
198 self
199 }
200}
201
202impl<US> Router<US> {
203 pub fn layer<Layer>(mut self, layer: Layer) -> Self
204 where
205 US: 'static,
206 US: Clone,
207 US: Send + Sync,
208 Layer: Clone + Send + Sync + 'static,
209 Layer: tower_layer::Layer<axum::routing::Route>,
210 Layer::Service: tower_service::Service<
211 hyper::Request<hyper::Body>,
212 Error = std::convert::Infallible,
213 >,
214 Layer::Service: Clone + Send + 'static,
215 <Layer::Service as tower_service::Service<
216 hyper::Request<hyper::Body>,
217 >>::Response: axum::response::IntoResponse + 'static,
218 <Layer::Service as tower_service::Service<
219 hyper::Request<hyper::Body>,
220 >>::Future: Send + 'static,
221 {
222 if let Some(current_action) = self.action.take() {
223 self.action.replace(current_action.layer(layer));
224 }
225 self
226 }
227
228 pub fn route_layer<Layer>(mut self, layer: Layer) -> Self
229 where
230 US: 'static,
231 US: Clone,
232 US: Send + Sync,
233 Layer: Clone + Send + Sync + 'static,
234 Layer: tower_layer::Layer<axum::routing::Route>,
235 Layer::Service: tower_service::Service<
236 hyper::Request<hyper::Body>,
237 Error = std::convert::Infallible,
238 >,
239 Layer::Service: Clone + Send + 'static,
240 <Layer::Service as tower_service::Service<
241 hyper::Request<hyper::Body>,
242 >>::Response: axum::response::IntoResponse + 'static,
243 <Layer::Service as tower_service::Service<
244 hyper::Request<hyper::Body>,
245 >>::Future: Send + 'static,
246 {
247 if let Some(current_action) = self.action.take() {
248 self.action.replace(current_action.route_layer(layer));
249 }
250 self
251 }
252}
253
254macro_rules! router_impl {
259 (
260 impl RouterInterface for
261 $(
262 | ( $($generic:ident),* )
263 )* {}
264 ) => {
265 $(
266 impl<State, $($generic),*> super::interface::RouterExt for ($($generic),*)
267 where
268 State: crate::state::StateInterface,
269 $(
270 $generic: super::interface::RouterExt<State = State>,
271 )*
272 {
273 type State = State;
274
275 fn routes() -> RouteCollection<Self::State> {
276 let mut router_collection = Self::router_collection();
277
278 $( router_collection.extend($generic::routes()); )*
279
280 router_collection
281 }
282 }
283 )*
284 };
285}
286
287router_impl! {
288 impl RouterInterface for
289 | (A, B)
290 | (A, B, C)
291 | (A, B, C, D)
292 | (A, B, C, D, E)
293 | (A, B, C, D, E, F)
294 | (A, B, C, D, E, F, G)
295 | (A, B, C, D, E, F, G, H)
296 | (A, B, C, D, E, F, G, H, I)
297 | (A, B, C, D, E, F, G, H, I, J)
298 | (A, B, C, D, E, F, G, H, I, J, K)
299 | (A, B, C, D, E, F, G, H, I, J, K, L)
300 | (A, B, C, D, E, F, G, H, I, J, K, L, M)
301 | (A, B, C, D, E, F, G, H, I, J, K, L, M, N)
302 | (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O)
303 | (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P)
304 | (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q)
305 | (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R)
306 | (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S)
307 | (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T)
308 | (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U)
309 | (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V)
310 | (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W)
311 | (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X)
312 | (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y)
313 | (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z)
314 {}
315}