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}