Skip to content

Commit 443a14c

Browse files
committed
feat: add router merge
1 parent 1ce77c3 commit 443a14c

3 files changed

Lines changed: 52 additions & 11 deletions

File tree

src/main.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,10 @@ async fn main() {
140140
.realm("Admin Area")
141141
.into_middleware();
142142

143+
let mut r2 = tako::router::Router::new();
144+
r2.route(Method::GET, "/compression", compression);
145+
r.merge(r2);
146+
143147
r.route(Method::GET, "/compression", compression)
144148
.middleware(basic);
145149

src/route.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
/// HTTP method, handler, and any associated middleware. It also provides utilities for
55
/// matching paths and extracting parameters from dynamic segments.
66
use std::{
7-
collections::HashMap,
7+
collections::{HashMap, VecDeque},
88
sync::{Arc, RwLock},
99
};
1010

@@ -39,7 +39,7 @@ pub struct Route {
3939
pub param_names: Vec<String>,
4040
pub method: Method,
4141
pub handler: BoxHandler,
42-
pub middlewares: RwLock<Vec<BoxMiddleware>>,
42+
pub middlewares: RwLock<VecDeque<BoxMiddleware>>,
4343
pub tsr: bool,
4444
}
4545

@@ -65,7 +65,7 @@ impl Route {
6565
param_names,
6666
method,
6767
handler,
68-
middlewares: RwLock::new(Vec::new()),
68+
middlewares: RwLock::new(VecDeque::new()),
6969
tsr: tsr.unwrap_or(false),
7070
}
7171
}
@@ -92,7 +92,7 @@ impl Route {
9292
Box::pin(async move { fut.await.into_response() })
9393
});
9494

95-
self.middlewares.write().unwrap().push(mw);
95+
self.middlewares.write().unwrap().push_back(mw);
9696
self
9797
}
9898

src/router.rs

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -298,13 +298,50 @@ impl Router {
298298
self.plugins.iter().map(|plugin| plugin.as_ref()).collect()
299299
}
300300

301+
/// Merges another `Router` into the current `Router`.
302+
///
303+
/// This method combines the routes and middlewares of the provided `Router`
304+
/// into the current `Router`. Routes from the other `Router` are added to
305+
/// the current one, and its middlewares are prepended to the route-level
306+
/// middlewares of the merged routes.
307+
///
308+
/// # Arguments
309+
///
310+
/// * `other` - The `Router` instance to merge into the current `Router`.
311+
///
312+
/// # Behavior
313+
///
314+
/// - Routes from the `other` router are added to the current router.
315+
/// - Middlewares defined at the router level in the `other` router are
316+
/// prepended to the route-level middlewares of the merged routes.
317+
///
318+
/// # Example
319+
///
320+
/// ```rust
321+
/// use tako::router::Router;
322+
/// use http::Method;
323+
///
324+
/// let mut router1 = Router::new();
325+
/// router1.route(Method::GET, "/example1", |req| async move {
326+
/// Ok(req)
327+
/// });
328+
///
329+
/// let mut router2 = Router::new();
330+
/// router2.route(Method::POST, "/example2", |req| async move {
331+
/// Ok(req)
332+
/// });
333+
///
334+
/// router1.merge(router2);
335+
/// ```
301336
pub fn merge(&mut self, other: Router) {
302-
other.routes.into_iter().for_each(|route| {});
303-
other
304-
.middlewares
305-
.read()
306-
.unwrap()
307-
.iter()
308-
.for_each(|middleware| {});
337+
other.routes.iter_mut().for_each(|mut entry| {
338+
let (key, route) = entry.pair_mut();
339+
// add router level middlewares at the beginning of the middlewares on route level
340+
for mw in other.middlewares.read().unwrap().iter().rev() {
341+
route.middlewares.write().unwrap().push_front(mw.clone());
342+
}
343+
344+
self.routes.insert(key.to_owned(), route.to_owned());
345+
});
309346
}
310347
}

0 commit comments

Comments
 (0)