Skip to main content

tourist_types/path/
relative.rs

1use std::path::PathBuf;
2
3pub type Component = String;
4
5#[derive(Debug, PartialEq, Eq, Hash)]
6pub struct RelativePathBuf(Vec<Component>);
7
8impl RelativePathBuf {
9    pub fn join(mut self, c: Component) -> Self {
10        self.0.push(c);
11        self
12    }
13
14    pub fn from_components<I: Iterator<Item = Component>>(i: I) -> Self {
15        RelativePathBuf(i.collect())
16    }
17
18    pub fn as_path_buf(&self) -> PathBuf {
19        let mut p = PathBuf::new();
20        self.0.iter().for_each(|c| p.push(c));
21        p
22    }
23
24    pub fn as_git_path(&self) -> String {
25        self.0
26            .iter()
27            .map(|x| x.clone())
28            .collect::<Vec<_>>()
29            .join("/")
30    }
31}
32
33impl From<&str> for RelativePathBuf {
34    fn from(s: &str) -> Self {
35        RelativePathBuf::from_components(s.split("/").filter_map(|x| {
36            if x.is_empty() {
37                None
38            } else {
39                Some(x.to_owned())
40            }
41        }))
42    }
43}
44
45#[cfg(test)]
46mod tests {
47    use super::RelativePathBuf;
48
49    #[test]
50    fn join_works() {
51        let mut path = RelativePathBuf(vec![]).join("some".to_owned());
52        assert_eq!(path.0.len(), 1);
53        assert_eq!(path.0[0], "some");
54
55        path = path.join("dir".to_owned());
56        assert_eq!(path.0.len(), 2);
57        assert_eq!(path.0[0], "some");
58        assert_eq!(path.0[1], "dir");
59    }
60
61    #[test]
62    fn from_components_works() {
63        let path =
64            RelativePathBuf::from_components(vec!["some".to_owned(), "dir".to_owned()].into_iter());
65        assert_eq!(path.0.len(), 2);
66        assert_eq!(path.0[0], "some");
67        assert_eq!(path.0[1], "dir");
68    }
69
70    #[test]
71    fn from_str_works() {
72        {
73            let path: RelativePathBuf = "some/dir".into();
74            assert_eq!(path.0.len(), 2);
75            assert_eq!(path.0[0], "some");
76            assert_eq!(path.0[1], "dir");
77        }
78
79        {
80            let path: RelativePathBuf = "some".into();
81            assert_eq!(path.0.len(), 1);
82            assert_eq!(path.0[0], "some");
83        }
84
85        {
86            let path: RelativePathBuf = "".into();
87            assert_eq!(path.0.len(), 0);
88        }
89
90        {
91            let path: RelativePathBuf = "/some//dir/".into();
92            assert_eq!(path.0.len(), 2);
93            assert_eq!(path.0[0], "some");
94            assert_eq!(path.0[1], "dir");
95        }
96    }
97}