little_hyper/
router.rs

1use crate::{
2    path::{self, path_regex},
3    Request, Response,
4};
5use std::collections::HashMap;
6
7pub type RouteHandler = dyn Fn(&mut Request, &mut Response) + 'static;
8
9/// Router
10///
11///
12#[derive(Default)]
13pub struct Router {
14    /// Routes
15    ///
16    /// All get method routes are stored here.
17    routes: HashMap<String, Box<RouteHandler>>,
18}
19
20impl Router {
21    /// Router
22    ///
23    /// New instance of router.
24    pub fn new() -> Self {
25        Self {
26            routes: HashMap::new(),
27        }
28    }
29
30    /// Get
31    ///
32    /// Add get route.
33    pub fn get<CB>(&mut self, path: &str, callback: CB)
34    where
35        CB: Fn(&mut Request, &mut Response) + 'static,
36    {
37        self.route("GET", path, callback);
38    }
39
40    /// Route
41    ///
42    /// Add route to router
43    pub fn route<CB>(&mut self, _method: &str, path: &str, callback: CB)
44    where
45        CB: Fn(&mut Request, &mut Response) + 'static,
46    {
47        let sanitized_path = path::sanitize_path(path);
48        let regex_path = path_regex::path_to_regex(&sanitized_path);
49
50        self.routes.insert(regex_path, Box::new(callback));
51    }
52
53    /// Merge Router
54    ///
55    /// 
56    pub fn merge_router(&mut self, target_router: Router) {
57        target_router.routes.into_iter().for_each(|(key, value)| {
58            self.routes.insert(key, value);
59        });
60    }
61
62    /// Get Handler
63    ///
64    /// - `pathname` must be got from request. Or, you will get a unknown handler.
65    pub fn get_handler(&self, request: &mut Request) -> Option<&Box<RouteHandler>> {
66        // 1st dynamic routes
67        // 2nd normal routes
68        let key = self.routes.keys().find(|regex_path| {
69            if let Some(params) = path_regex::path_regex_matcher(regex_path, &request.pathname) {
70                request.params = params;
71
72                return true;
73            }
74            false
75        });
76
77        if let Some(key) = key {
78            return self.routes.get(key);
79        }
80
81        None
82    }
83}