ross_http/
router.rs

1extern crate alloc;
2
3use alloc::boxed::Box;
4use alloc::string::{String, ToString};
5use alloc::vec;
6use alloc::vec::Vec;
7
8use crate::method::Method;
9use crate::request::Request;
10use crate::response::Response;
11use crate::uri::path::Path;
12
13type RequestHandler<'a> = Box<dyn FnMut(Request, Vec<String>) -> Response + 'a>;
14
15#[derive(Debug, Clone)]
16pub struct HttpRoute {
17    pub method: Method,
18    pub path: Path,
19}
20
21pub struct HttpRouter<'a> {
22    routes: Vec<(HttpRoute, RequestHandler<'a>)>,
23    not_found_handler: RequestHandler<'a>,
24}
25
26impl<'a> HttpRouter<'a> {
27    pub fn new(not_found_handler: RequestHandler<'a>) -> Self {
28        Self {
29            routes: vec![],
30            not_found_handler,
31        }
32    }
33
34    pub fn add_route(&mut self, route: HttpRoute, handler: RequestHandler<'a>) {
35        self.routes.push((route, handler));
36    }
37
38    pub fn handle_request(&mut self, request: Request) -> Response {
39        let request_path = match &request.uri.path {
40            Some(path) => path.clone(),
41            None => Path { segments: vec![] },
42        };
43
44        for (route, handler) in self.routes.iter_mut() {
45            if route.method == request.method {
46                if route.path.segments.len() != request_path.segments.len() {
47                    continue;
48                }
49
50                let mut variables = vec![];
51                let mut matched = true;
52
53                for (i, route_segment) in route.path.segments.iter().enumerate() {
54                    let request_segment = request_path.segments.iter().nth(i).unwrap();
55
56                    if *route_segment == "{}".to_string() {
57                        variables.push(request_segment.clone());
58                    } else if *route_segment == *request_segment {
59                        continue;
60                    } else {
61                        matched = false;
62                        break;
63                    }
64                }
65
66                if matched {
67                    return handler(request, variables);
68                }
69            }
70        }
71
72        (self.not_found_handler)(request, vec![])
73    }
74}