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
pub mod filter;
mod router;
pub use filter::*;
pub use router::{DetectMatched, Router};

use std::collections::HashMap;
pub type PathParams = HashMap<String, String>;

#[derive(Debug, Eq, PartialEq)]
pub struct PathState {
    pub(crate) url_path: String,
    pub(crate) cursor: usize,
    pub(crate) params: PathParams,
}
impl PathState {
    pub fn new(url_path: &str) -> Self {
        let url_path = url_path.trim_start_matches('/').trim_end_matches('/');
        PathState {
            url_path: decode_url_path_safely(url_path),
            cursor: 0,
            params: PathParams::new(),
        }
    }
    pub(crate) fn ended(&self) -> bool {
        self.cursor >= self.url_path.len()
    }
}

fn decode_url_path_safely(path: &str) -> String {
    percent_encoding::percent_decode_str(path)
        .decode_utf8_lossy()
        .to_string()
}