little_hyper/path/
mod.rs

1pub mod path_regex;
2use crate::query::{QueryData, QUERY_START_WITH};
3
4/// Path
5///
6///
7/// ```fn my_path(Path(path): Path<MyStruct>) { }```
8// #[derive(Debug)]
9// pub struct Path<T>(T);
10
11// impl<T> Extractor<T> for Path<T> {
12//     fn inner(&self) -> &T {
13//         &self.0
14//     }
15// }
16
17#[derive(Debug)]
18pub struct PathData {
19    pub path: String,
20    pub pathname: String,
21    pub querystring: String,
22    pub query: QueryData,
23}
24
25impl PathData {
26    pub fn new(path: &str) -> Self {
27        let path = sanitize_path(path);
28
29        let (pathname, querystring) = path.split_once(QUERY_START_WITH).unwrap_or((&path, &""));
30
31        Self {
32            path: path.to_string(),
33            pathname: pathname.to_string(),
34            querystring: querystring.to_string(),
35            query: QueryData::from(querystring),
36        }
37    }
38}
39
40// remove noise of path
41pub fn sanitize_path(path: &str) -> String {
42    let path = path.replace('\\', "/");
43    let path = path.replace('/', "/");
44    let mut path = path.replace("/?", "?");
45
46    if path.len() > 1 && path.ends_with('/') {
47        path.pop();
48    }
49
50    path
51}
52
53#[cfg(test)]
54mod tests {
55    use super::*;
56
57    #[test]
58    fn test_sanitize_path() {
59        assert_eq!(sanitize_path("/abc/xyz/"), "/abc/xyz");
60        assert_eq!(sanitize_path("/abc/1/"), "/abc/1");
61        assert_eq!(sanitize_path("/abc/?a=1"), "/abc?a=1");
62    }
63
64    #[test]
65    fn test_path_data() {
66        let path_one = PathData::new("/users/?userId=10");
67
68        assert!(path_one.path == "/users?userId=10");
69        assert!(path_one.pathname == "/users");
70        assert!(path_one.querystring == "userId=10");
71        assert!(path_one.query.len() == 1);
72    }
73}