tako_rs_core/router/
registration.rs1use std::sync::Arc;
4
5use http::Method;
6
7use super::Router;
8use crate::handler::BoxHandler;
9use crate::handler::Handler;
10use crate::route::Route;
11
12impl Router {
13 pub fn route<H, T>(&mut self, method: Method, path: &str, handler: H) -> Arc<Route>
42 where
43 H: Handler<T> + Clone + 'static,
44 {
45 let final_path = self.apply_pending_prefix(path);
46 let route = Arc::new(Route::new(
47 final_path.clone(),
48 method.clone(),
49 BoxHandler::new::<H, T>(handler),
50 None,
51 ));
52
53 if let Err(err) = self
54 .inner
55 .get_or_default_mut(&method)
56 .insert(final_path, route.clone())
57 {
58 panic!("Failed to register route: {err}");
59 }
60
61 self
62 .routes
63 .get_or_default_mut(&method)
64 .push(Arc::downgrade(&route));
65
66 route
67 }
68
69 pub(crate) fn apply_pending_prefix(&self, path: &str) -> String {
72 match &self.pending_prefix {
73 None => path.to_string(),
74 Some(prefix) => {
75 let prefix = prefix.trim_end_matches('/');
76 if path.is_empty() || path == "/" {
77 if prefix.is_empty() {
78 "/".to_string()
79 } else {
80 prefix.to_string()
81 }
82 } else if path.starts_with('/') {
83 let mut s = String::with_capacity(prefix.len() + path.len());
84 s.push_str(prefix);
85 s.push_str(path);
86 s
87 } else {
88 let mut s = String::with_capacity(prefix.len() + 1 + path.len());
89 s.push_str(prefix);
90 s.push('/');
91 s.push_str(path);
92 s
93 }
94 }
95 }
96 }
97
98 #[inline]
100 pub fn get<H, T>(&mut self, path: &str, handler: H) -> Arc<Route>
101 where
102 H: Handler<T> + Clone + 'static,
103 {
104 self.route(Method::GET, path, handler)
105 }
106
107 #[inline]
109 pub fn post<H, T>(&mut self, path: &str, handler: H) -> Arc<Route>
110 where
111 H: Handler<T> + Clone + 'static,
112 {
113 self.route(Method::POST, path, handler)
114 }
115
116 #[inline]
118 pub fn put<H, T>(&mut self, path: &str, handler: H) -> Arc<Route>
119 where
120 H: Handler<T> + Clone + 'static,
121 {
122 self.route(Method::PUT, path, handler)
123 }
124
125 #[inline]
127 pub fn delete<H, T>(&mut self, path: &str, handler: H) -> Arc<Route>
128 where
129 H: Handler<T> + Clone + 'static,
130 {
131 self.route(Method::DELETE, path, handler)
132 }
133
134 #[inline]
136 pub fn patch<H, T>(&mut self, path: &str, handler: H) -> Arc<Route>
137 where
138 H: Handler<T> + Clone + 'static,
139 {
140 self.route(Method::PATCH, path, handler)
141 }
142
143 #[inline]
145 pub fn head<H, T>(&mut self, path: &str, handler: H) -> Arc<Route>
146 where
147 H: Handler<T> + Clone + 'static,
148 {
149 self.route(Method::HEAD, path, handler)
150 }
151
152 #[inline]
154 pub fn options<H, T>(&mut self, path: &str, handler: H) -> Arc<Route>
155 where
156 H: Handler<T> + Clone + 'static,
157 {
158 self.route(Method::OPTIONS, path, handler)
159 }
160
161 pub fn route_with_tsr<H, T>(&mut self, method: Method, path: &str, handler: H) -> Arc<Route>
186 where
187 H: Handler<T> + Clone + 'static,
188 {
189 assert!(path != "/", "Cannot route with TSR for root path");
190
191 let final_path = self.apply_pending_prefix(path);
192 let route = Arc::new(Route::new(
193 final_path.clone(),
194 method.clone(),
195 BoxHandler::new::<H, T>(handler),
196 Some(true),
197 ));
198
199 if let Err(err) = self
200 .inner
201 .get_or_default_mut(&method)
202 .insert(final_path, route.clone())
203 {
204 panic!("Failed to register route: {err}");
205 }
206
207 self
208 .routes
209 .get_or_default_mut(&method)
210 .push(Arc::downgrade(&route));
211
212 route
213 }
214}