little_hyper/
router.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
use crate::{
    path::{self, path_regex},
    Request, Response,
};
use std::collections::HashMap;

pub type RouteHandler = dyn Fn(&mut Request, &mut Response) + 'static;

/// Router
///
///
#[derive(Default)]
pub struct Router {
    /// Routes
    ///
    /// All get method routes are stored here.
    routes: HashMap<String, Box<RouteHandler>>,
}

impl Router {
    /// Router
    ///
    /// New instance of router.
    pub fn new() -> Self {
        Self {
            routes: HashMap::new(),
        }
    }

    /// Get
    ///
    /// Add get route.
    pub fn get<CB>(&mut self, path: &str, callback: CB)
    where
        CB: Fn(&mut Request, &mut Response) + 'static,
    {
        self.route("GET", path, callback);
    }

    /// Route
    ///
    /// Add route to router
    pub fn route<CB>(&mut self, _method: &str, path: &str, callback: CB)
    where
        CB: Fn(&mut Request, &mut Response) + 'static,
    {
        let sanitized_path = path::sanitize_path(path);
        let regex_path = path_regex::path_to_regex(&sanitized_path);

        self.routes.insert(regex_path, Box::new(callback));
    }

    /// Merge Router
    ///
    /// 
    pub fn merge_router(&mut self, target_router: Router) {
        target_router.routes.into_iter().for_each(|(key, value)| {
            self.routes.insert(key, value);
        });
    }

    /// Get Handler
    ///
    /// - `pathname` must be got from request. Or, you will get a unknown handler.
    pub fn get_handler(&self, request: &mut Request) -> Option<&Box<RouteHandler>> {
        // 1st dynamic routes
        // 2nd normal routes
        let key = self.routes.keys().find(|regex_path| {
            if let Some(params) = path_regex::path_regex_matcher(regex_path, &request.pathname) {
                request.params = params;

                return true;
            }
            false
        });

        if let Some(key) = key {
            return self.routes.get(key);
        }

        None
    }
}