1use std::{borrow::BorrowMut, collections::HashMap, fmt::Debug};
2
3use http::Method;
4
5use crate::{handler::Handler, middleware::Middleware, route::Route};
6
7#[derive(Clone, Debug, Default)]
8pub struct Endpoint {
9 path: String,
10 method_handler: HashMap<Method, Handler>,
11}
12
13impl Endpoint {
14 fn new() -> Self {
15 Self::default()
16 }
17
18 fn path(&mut self, path: &str) -> Self {
19 self.path = path.to_owned();
20 self.clone()
21 }
22
23 fn method_handler(&mut self, method: &Method, handler: &Handler) -> Self {
24 self.method_handler.insert(method.clone(), handler.clone());
25 self.clone()
26 }
27}
28
29#[derive(Clone, Default)]
30pub struct Router {
31 index: usize,
32 index_endpoint: HashMap<usize, Endpoint>,
33 path_index: matchit::Router<usize>,
34}
35
36impl Debug for Router {
37 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
38 f.debug_struct("Router")
39 .field("index", &self.index)
40 .field("index_endpoint", &self.index_endpoint)
41 .finish()
42 }
43}
44
45impl Router {
46 pub fn new() -> Self {
47 Self::default()
48 }
49
50 pub fn group(&mut self, path: &str, router: Router) -> Self {
51 if !path.starts_with('/') {
52 panic!("group routes must start with '/'");
53 }
54
55 for (_, endpoint) in router.index_endpoint {
56 let path = format!("{}{}", path, endpoint.path);
57 for (method, hadnler) in endpoint.method_handler {
58 self.route((method, path.clone(), hadnler));
59 }
60 }
61
62 self.clone()
63 }
64
65 pub fn route<T>(&mut self, route: T) -> Self
66 where
67 T: Into<Route>,
68 {
69 let Route {
70 method,
71 path,
72 handler,
73 } = route.into();
74
75 if let Ok(matched) = self.path_index.at(&path) {
76 if let Some(endpoint) = self.index_endpoint.get_mut(matched.value) {
77 endpoint.method_handler.insert(method, handler);
78 }
79 } else {
80 let index = self.index;
81 self.path_index
82 .insert(&path, index)
83 .expect("path_index insert failed");
84 let endpoint = Endpoint::new()
85 .path(&path)
86 .method_handler(&method, &handler);
87 self.index_endpoint.insert(index, endpoint);
88 self.index += 1;
89 };
90
91 self.clone()
92 }
93
94 pub fn merge(&mut self, router: Router) -> Self {
95 for (_, endpoint) in router.index_endpoint {
96 for (method, hadnler) in endpoint.method_handler {
97 self.route((method, endpoint.path.clone(), hadnler));
98 }
99 }
100
101 self.clone()
102 }
103
104 pub fn get_handler(&self, method: &Method, path: &str) -> Option<(String, Handler)> {
105 if let Ok(matchit) = self.path_index.at(path) {
106 if let Some(endpoint) = self.index_endpoint.get(matchit.value) {
107 if let Some(handler) = endpoint.method_handler.get(method) {
108 return Some((endpoint.path.clone(), handler.clone()));
109 }
110 }
111 }
112
113 None
114 }
115
116 pub fn middleware<T>(&mut self, middleware: T) -> Self
117 where
118 T: Into<Box<dyn Middleware>>,
119 {
120 let middleware = middleware.into();
121 for endpoint in self.index_endpoint.borrow_mut().values_mut() {
122 for handler in endpoint.method_handler.borrow_mut().values_mut() {
123 handler.middleware(middleware.clone());
124 }
125 }
126
127 self.clone()
128 }
129}