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
use crate::common::default::default;

pub fn normalize(path: &str) -> String {
    let path_split: Vec<_> = path.split('/').collect();
    let mut result_split: Vec<&str> = Vec::new();
    for &dir in path_split.iter() {
        match dir {
            "" => {}
            ".." => {
                let last = result_split.last();
                match last {
                    Some(x) if x != &".." => {
                        result_split.pop();
                    }
                    _ => {
                        result_split.push(dir);
                    }
                }
            }
            _ => {
                result_split.push(dir);
            }
        }
    }
    result_split.join("/")
}

pub fn concat(a: &str, b: &str) -> String {
    let mut concat = a.to_string();
    concat.push('/');
    concat.push_str(b);
    normalize(&concat)
}

pub fn split(path: &str) -> (&str, &str) {
    match path.rsplit_once('/') {
        None => (default(), path),
        Some(t) => t,
    }
}

#[cfg(test)]
mod test {
    use wasm_bindgen_test::wasm_bindgen_test;

    use crate::parser::path::{concat, normalize};

    #[test]
    #[wasm_bindgen_test]
    fn test_norm() {
        let norm = normalize("../../dir/file.json");
        assert_eq!(norm, "../../dir/file.json");

        let norm = normalize("../../dir/../file.json");
        assert_eq!(norm, "../../file.json");
    }

    #[test]
    #[wasm_bindgen_test]
    fn test_concat() {
        let result = concat("a", "b");
        assert_eq!(result, "a/b");

        let result = concat("a///b/", "c");
        assert_eq!(result, "a/b/c");

        let result = concat("a/../b/..", "c");
        assert_eq!(result, "c");
    }
}