axum_distributed_routing/
lib.rs1pub use axum_distributed_routing_macros::*;
2pub use inventory;
3
4use axum::routing::Router;
5
6pub trait Route {
16 type State: Clone + Send + Sync + 'static;
17
18 fn attach(&self, router: Router<Self::State>, level: usize) -> Router<Self::State>;
19
20 fn path(&self) -> &'static str;
21}
22
23#[macro_export]
32macro_rules! route_group {
33 ($vis:vis $name:ident, $type:ty, $parent:ident, $path:literal) => {
34 $crate::route_group!($vis $name, $type);
35 $crate::inventory::submit!($parent::new($path, |router, level| {
36 router.nest($path, $crate::create_router::<$name>(level + 4))
37 }));
38 };
39 ($vis:vis $name:ident, $type:ty) => {
40 #[derive(Copy, Clone, Debug)]
41 $vis struct $name {
42 path: &'static str,
43 handler: fn(axum::routing::Router<$type>, usize) -> axum::routing::Router<$type>,
44 }
45
46 impl $name {
47 pub const fn new(
48 path: &'static str,
49 handler: fn(axum::routing::Router<$type>, usize) -> axum::routing::Router<$type>,
50 ) -> Self {
51 Self { path, handler }
52 }
53 }
54
55 impl $crate::Route for $name {
56 type State = $type;
57
58 fn attach(
59 &self,
60 router: axum::routing::Router<$type>,
61 level: usize,
62 ) -> axum::routing::Router<$type> {
63 (self.handler)(router, level)
64 }
65
66 fn path(&self) -> &'static str {
67 self.path
68 }
69 }
70
71 $crate::inventory::collect!($name);
72 };
73}
74
75#[macro_export]
77macro_rules! routes {
78 ($type:ty) => {
79 $crate::inventory::iter::<$type>
80 };
81}
82
83#[macro_export]
85macro_rules! create_router {
86 ($type:ty) => {
87 $crate::create_router::<$type>(0)
88 };
89}
90
91#[doc(hidden)]
92pub fn create_router<T: Route + 'static>(level: usize) -> Router<T::State>
93where
94 inventory::iter<T>: IntoIterator<Item = &'static T>,
95{
96 let mut router = Router::new();
97 for route in inventory::iter::<T> {
98 router = route.attach(router, level);
99 }
100 router
101}
102
103