1use std::sync::Arc;
2use crate::requests::Request;
3
4
5pub type Response = http::Response<Vec<u8>>;
6
7pub trait IntoResponse {
8 fn into_response(self) -> Response;
9}
10
11impl IntoResponse for Response {
12 fn into_response(self) -> Response {
13 self
14 }
15}
16
17impl IntoResponse for &'static str {
18 fn into_response(self) -> Response {
19 http::Response::builder()
20 .header(http::header::CONTENT_TYPE, "text/plain; charset=utf-8")
21 .body(self.as_bytes().to_vec())
22 .unwrap()
23 }
24}
25
26impl IntoResponse for String {
27 fn into_response(self) -> Response {
28 http::Response::builder()
29 .header(http::header::CONTENT_TYPE, "text/plain; charset=utf-8")
30 .body(self.into_bytes())
31 .unwrap()
32 }
33}
34
35pub struct Html<T>(pub T);
36impl<T: Into<String>> IntoResponse for Html<T> {
37 fn into_response(self) -> Response {
38 http::Response::builder()
39 .header(http::header::CONTENT_TYPE, "text/html; charset=utf-8")
40 .body(self.0.into().into_bytes())
41 .unwrap()
42 }
43}
44
45pub struct Json<T>(pub T);
46impl<T: serde::Serialize> IntoResponse for Json<T> {
47 fn into_response(self) -> Response {
48 let body = serde_json::to_vec(&self.0).unwrap_or_default();
49 http::Response::builder()
50 .header(http::header::CONTENT_TYPE, "application/json")
51 .body(body)
52 .unwrap()
53 }
54}
55
56pub struct Redirect {
57 url: String,
58}
59impl Redirect {
60 pub fn to(url: &str) -> Self {
61 Self { url: url.to_string() }
62 }
63}
64impl IntoResponse for Redirect {
65 fn into_response(self) -> Response {
66 http::Response::builder()
67 .status(http::StatusCode::SEE_OTHER)
68 .header(http::header::LOCATION, &self.url)
69 .body(Vec::new())
70 .unwrap()
71 }
72}
73
74impl IntoResponse for serde_json::Value {
75 fn into_response(self) -> Response {
76 Json(self).into_response()
77 }
78}
79
80impl IntoResponse for http::StatusCode {
81 fn into_response(self) -> Response {
82 http::Response::builder()
83 .status(self)
84 .body(Vec::new())
85 .unwrap()
86 }
87}
88
89impl<T: IntoResponse, E: IntoResponse> IntoResponse for Result<T, E> {
90 fn into_response(self) -> Response {
91 match self {
92 Ok(r) => r.into_response(),
93 Err(e) => e.into_response(),
94 }
95 }
96}
97
98impl<T: IntoResponse> IntoResponse for (http::StatusCode, T) {
99 fn into_response(self) -> Response {
100 let mut res = self.1.into_response();
101 *res.status_mut() = self.0;
102 res
103 }
104}
105
106#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
107pub struct State<T>(pub T);
108
109#[crate::async_trait]
110pub trait Handler<T>: Send + Sync + 'static {
111 async fn call(&self, req: Request) -> Response;
112}
113
114#[crate::async_trait]
115pub trait ErasedHandler: Send + Sync + 'static {
116 async fn call(&self, req: Request) -> Response;
117}
118
119pub struct HandlerWrapper<H, T> {
120 pub(crate) handler: H,
121 pub(crate) _marker: std::marker::PhantomData<T>,
122}
123
124#[crate::async_trait]
125impl<H, T> ErasedHandler for HandlerWrapper<H, T>
126where
127 H: Handler<T>,
128 T: Send + Sync + 'static,
129{
130 async fn call(&self, req: Request) -> Response {
131 self.handler.call(req).await
132 }
133}
134
135#[crate::async_trait]
137impl<F, Fut, R> Handler<()> for F
138where
139 F: Fn() -> Fut + Send + Sync + 'static,
140 Fut: std::future::Future<Output = R> + Send + 'static,
141 R: IntoResponse + Send + 'static,
142{
143 async fn call(&self, _req: Request) -> Response {
144 self().await.into_response()
145 }
146}
147
148#[crate::async_trait]
150impl<F, Fut, R> Handler<(Request,)> for F
151where
152 F: Fn(Request) -> Fut + Send + Sync + 'static,
153 Fut: std::future::Future<Output = R> + Send + 'static,
154 R: IntoResponse + Send + 'static,
155{
156 async fn call(&self, req: Request) -> Response {
157 self(req).await.into_response()
158 }
159}
160
161#[crate::async_trait]
163impl<F, Fut, R> Handler<(State<crate::AppState>, Request)> for F
164where
165 F: Fn(State<crate::AppState>, Request) -> Fut + Send + Sync + 'static,
166 Fut: std::future::Future<Output = R> + Send + 'static,
167 R: IntoResponse + Send + 'static,
168{
169 async fn call(&self, req: Request) -> Response {
170 let state = State(req.state.clone());
171 self(state, req).await.into_response()
172 }
173}
174
175#[derive(Clone)]
176pub struct MethodRouter {
177 pub(crate) handlers: Vec<(http::Method, Arc<dyn ErasedHandler>)>,
178}
179
180pub fn get<H, T>(handler: H) -> MethodRouter
181where
182 H: Handler<T>,
183 T: Send + Sync + 'static,
184{
185 let wrapped: Arc<dyn ErasedHandler> = Arc::new(HandlerWrapper {
186 handler,
187 _marker: std::marker::PhantomData,
188 });
189 MethodRouter {
190 handlers: vec![(http::Method::GET, wrapped)],
191 }
192}
193
194pub fn post<H, T>(handler: H) -> MethodRouter
195where
196 H: Handler<T>,
197 T: Send + Sync + 'static,
198{
199 let wrapped: Arc<dyn ErasedHandler> = Arc::new(HandlerWrapper {
200 handler,
201 _marker: std::marker::PhantomData,
202 });
203 MethodRouter {
204 handlers: vec![(http::Method::POST, wrapped)],
205 }
206}
207
208pub fn put<H, T>(handler: H) -> MethodRouter
209where
210 H: Handler<T>,
211 T: Send + Sync + 'static,
212{
213 let wrapped: Arc<dyn ErasedHandler> = Arc::new(HandlerWrapper {
214 handler,
215 _marker: std::marker::PhantomData,
216 });
217 MethodRouter {
218 handlers: vec![(http::Method::PUT, wrapped)],
219 }
220}
221
222pub fn patch<H, T>(handler: H) -> MethodRouter
223where
224 H: Handler<T>,
225 T: Send + Sync + 'static,
226{
227 let wrapped: Arc<dyn ErasedHandler> = Arc::new(HandlerWrapper {
228 handler,
229 _marker: std::marker::PhantomData,
230 });
231 MethodRouter {
232 handlers: vec![(http::Method::PATCH, wrapped)],
233 }
234}
235
236pub fn delete<H, T>(handler: H) -> MethodRouter
237where
238 H: Handler<T>,
239 T: Send + Sync + 'static,
240{
241 let wrapped: Arc<dyn ErasedHandler> = Arc::new(HandlerWrapper {
242 handler,
243 _marker: std::marker::PhantomData,
244 });
245 MethodRouter {
246 handlers: vec![(http::Method::DELETE, wrapped)],
247 }
248}
249
250impl MethodRouter {
251 pub fn get<H, T>(mut self, handler: H) -> Self
252 where
253 H: Handler<T>,
254 T: Send + Sync + 'static,
255 {
256 let wrapped: Arc<dyn ErasedHandler> = Arc::new(HandlerWrapper {
257 handler,
258 _marker: std::marker::PhantomData,
259 });
260 self.handlers.push((http::Method::GET, wrapped));
261 self
262 }
263
264 pub fn post<H, T>(mut self, handler: H) -> Self
265 where
266 H: Handler<T>,
267 T: Send + Sync + 'static,
268 {
269 let wrapped: Arc<dyn ErasedHandler> = Arc::new(HandlerWrapper {
270 handler,
271 _marker: std::marker::PhantomData,
272 });
273 self.handlers.push((http::Method::POST, wrapped));
274 self
275 }
276
277 pub fn put<H, T>(mut self, handler: H) -> Self
278 where
279 H: Handler<T>,
280 T: Send + Sync + 'static,
281 {
282 let wrapped: Arc<dyn ErasedHandler> = Arc::new(HandlerWrapper {
283 handler,
284 _marker: std::marker::PhantomData,
285 });
286 self.handlers.push((http::Method::PUT, wrapped));
287 self
288 }
289
290 pub fn patch<H, T>(mut self, handler: H) -> Self
291 where
292 H: Handler<T>,
293 T: Send + Sync + 'static,
294 {
295 let wrapped: Arc<dyn ErasedHandler> = Arc::new(HandlerWrapper {
296 handler,
297 _marker: std::marker::PhantomData,
298 });
299 self.handlers.push((http::Method::PATCH, wrapped));
300 self
301 }
302
303 pub fn delete<H, T>(mut self, handler: H) -> Self
304 where
305 H: Handler<T>,
306 T: Send + Sync + 'static,
307 {
308 let wrapped: Arc<dyn ErasedHandler> = Arc::new(HandlerWrapper {
309 handler,
310 _marker: std::marker::PhantomData,
311 });
312 self.handlers.push((http::Method::DELETE, wrapped));
313 self
314 }
315}
316
317#[derive(Clone)]
318pub struct Router<S = ()> {
319 pub(crate) routes: Vec<Arc<Route>>,
320 pub(crate) middlewares: Vec<crate::middleware::MiddlewareFn>,
321 pub(crate) _marker: std::marker::PhantomData<fn() -> S>,
322}
323
324pub struct Route {
325 pub path: String,
326 pub handlers: Vec<(http::Method, Arc<dyn ErasedHandler>)>,
327}
328
329struct MiddlewareHandler {
330 mw: crate::middleware::MiddlewareFn,
331 next: Arc<dyn ErasedHandler>,
332}
333
334#[crate::async_trait]
335impl ErasedHandler for MiddlewareHandler {
336 async fn call(&self, req: Request) -> Response {
337 let chain = Arc::new(crate::middleware::MiddlewareChain::End(self.next.clone()));
338 let next = crate::middleware::Next { chain };
339 (self.mw)(req, next).await
340 }
341}
342
343impl<S> Router<S> {
344 pub fn new() -> Self {
345 Self {
346 routes: Vec::new(),
347 middlewares: Vec::new(),
348 _marker: std::marker::PhantomData,
349 }
350 }
351
352 pub fn route(mut self, path: &str, method_router: MethodRouter) -> Self {
353 self.routes.push(Arc::new(Route {
354 path: path.to_string(),
355 handlers: method_router.handlers,
356 }));
357 self
358 }
359
360 pub fn get_json<T>(self, path: &str, data: T) -> Self
361 where
362 T: serde::Serialize + Clone + Send + Sync + 'static,
363 {
364 let data_clone = data.clone();
365 self.route(path, get(move || {
366 let data = data_clone.clone();
367 async move {
368 Json(data)
369 }
370 }))
371 }
372
373 pub fn get_redirect(self, path: &str, to_url: &str) -> Self {
374 let to_url = to_url.to_string();
375 self.route(path, get(move || {
376 let to = to_url.clone();
377 async move {
378 Redirect::to(&to)
379 }
380 }))
381 }
382
383 pub fn get_view(self, path: &str, template: &'static str, context: serde_json::Value) -> Self {
384 let context_clone = context.clone();
385 self.route(path, get(move |req: Request| {
386 let ctx = context_clone.clone();
387 async move {
388 crate::view::view(&req, template, minijinja::Value::from_serialize(ctx))
389 }
390 }))
391 }
392
393 pub fn merge(mut self, other: Router<S>) -> Self {
394 for other_route in other.routes {
395 let mut handlers_with_mw = Vec::new();
396 for (method, handler) in &other_route.handlers {
397 let mut current_handler = handler.clone();
398 for mw in other.middlewares.iter().rev() {
399 let next_handler = current_handler.clone();
400 let mw_clone = mw.clone();
401 current_handler = Arc::new(MiddlewareHandler {
402 mw: mw_clone,
403 next: next_handler,
404 });
405 }
406 handlers_with_mw.push((method.clone(), current_handler));
407 }
408 self.routes.push(Arc::new(Route {
409 path: other_route.path.clone(),
410 handlers: handlers_with_mw,
411 }));
412 }
413 self
414 }
415
416 pub fn nest(mut self, prefix: &str, other: Router<S>) -> Self {
417 let clean_prefix = prefix.trim_end_matches('/');
418 for other_route in other.routes {
419 let mut handlers_with_mw = Vec::new();
420 for (method, handler) in &other_route.handlers {
421 let mut current_handler = handler.clone();
422 for mw in other.middlewares.iter().rev() {
423 let next_handler = current_handler.clone();
424 let mw_clone = mw.clone();
425 current_handler = Arc::new(MiddlewareHandler {
426 mw: mw_clone,
427 next: next_handler,
428 });
429 }
430 handlers_with_mw.push((method.clone(), current_handler));
431 }
432 let nested_path = format!("{}{}", clean_prefix, other_route.path);
433 self.routes.push(Arc::new(Route {
434 path: nested_path,
435 handlers: handlers_with_mw,
436 }));
437 }
438 self
439 }
440
441 pub fn layer(mut self, mw: crate::middleware::MiddlewareFn) -> Self {
442 self.middlewares.push(mw);
443 self
444 }
445}