1use axum::{
2 routing::{get, post, put, patch, delete, head, connect, trace, options},
3 handler::Handler
4};
5use crate::{
6 route::{Method, Route},
7 canonicalize_path
8};
9
10macro_rules! add_method {
11 ($method:expr, $name:ident, $axum_fn:ident) => {
12 pub fn $name<H, T>(&mut self, path: &str, handler: H) -> &mut Self
13 where
14 H: Handler<T, S>,
15 T: 'static,
16 {
17 let combined_path = format!("{}{}", self.prefix, path);
18
19 self.routes.push(Route {
20 method: $method,
21 path: canonicalize_path(&combined_path),
22 handler: $axum_fn(handler),
23 });
24
25 self
26 }
27 };
28}
29
30#[derive(Clone, Debug)]
31pub struct APIRouter<S = ()> {
32 pub prefix: String,
33 pub routes: Vec<Route<S>>,
34}
35
36impl<S> APIRouter<S>
37where
38 S: Clone + Send + Sync + 'static, {
40 pub fn new(prefix: impl Into<String>) -> Self {
41 Self {
42 prefix: canonicalize_path(&prefix.into()),
43 routes: Vec::new(),
44 }
45 }
46
47 pub fn add_route(&mut self, route: Route<S>) {
48 self.routes.push(route);
49 }
50
51 pub fn include_router(&mut self, router: APIRouter<S>) {
54 for v in &router.routes {
55 let combined_path = format!("{}{}", self.prefix, v.path);
56 self.add_route(Route {
57 method: v.method.clone(),
58 path: combined_path,
59 handler: v.handler.clone()
60 });
61 }
62 }
63
64 add_method!(Method::Get, get, get);
65 add_method!(Method::Post, post, post);
66 add_method!(Method::Put, put, put);
67 add_method!(Method::Patch, patch, patch);
68 add_method!(Method::Delete, delete, delete);
69 add_method!(Method::Head, head, head);
70 add_method!(Method::Options, options, options);
71 add_method!(Method::Trace, trace, trace);
72 add_method!(Method::Connect, connect, connect);
73}
74