restless_web/
route.rs

1use crate::request::Req;
2use crate::response::Res;
3use derivative::Derivative;
4
5#[derive(Debug)]
6pub enum PathItemType {
7    Static,
8    Dynamic,
9}
10
11#[derive(Debug)]
12pub struct PathItem<'a> {
13    pub r#type: PathItemType,
14    pub value: &'a str,
15}
16
17impl PathItem<'_> {
18    pub fn new(value: &str, r#type: PathItemType) -> PathItem {
19        PathItem { value, r#type }
20    }
21}
22
23pub type RouteCallback = fn(Req, Res) -> Res;
24
25#[derive(Derivative)]
26#[derivative(Debug)]
27pub struct Route<'a> {
28    pub paths: Vec<PathItem<'a>>,
29    pub method: Option<&'a str>,
30    #[derivative(Debug = "ignore")]
31    pub callback: RouteCallback,
32}
33
34impl Route<'_> {
35    pub fn new<'a>(path: &'a str, callback: RouteCallback, method: Option<&'a str>) -> Route<'a> {
36        Route {
37            paths: Route::parse_path(path),
38            method,
39            callback,
40        }
41    }
42
43    fn parse_path(path: &str) -> Vec<PathItem> {
44        if !path.starts_with('/') {
45            panic!("Path {} should starts with /", path)
46        };
47
48        match path {
49            "/" => {
50                vec![PathItem::new("/", PathItemType::Static)]
51            }
52            _ => path
53                .split('/')
54                .map(|path_part| {
55                    let path_type = if path_part.starts_with(':') {
56                        PathItemType::Dynamic
57                    } else {
58                        PathItemType::Static
59                    };
60
61                    PathItem::new(path_part, path_type)
62                })
63                .collect(),
64        }
65    }
66}