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 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
use std::path::PathBuf; pub type Component = String; #[derive(Debug, PartialEq, Eq, Hash)] pub struct RelativePathBuf(Vec<Component>); impl RelativePathBuf { pub fn join(mut self, c: Component) -> Self { self.0.push(c); self } pub fn from_components<I: Iterator<Item = Component>>(i: I) -> Self { RelativePathBuf(i.collect()) } pub fn as_path_buf(&self) -> PathBuf { let mut p = PathBuf::new(); self.0.iter().for_each(|c| p.push(c)); p } pub fn as_git_path(&self) -> String { self.0 .iter() .map(|x| x.clone()) .collect::<Vec<_>>() .join("/") } } impl From<&str> for RelativePathBuf { fn from(s: &str) -> Self { RelativePathBuf::from_components(s.split("/").filter_map(|x| { if x.is_empty() { None } else { Some(x.to_owned()) } })) } } #[cfg(test)] mod tests { use super::RelativePathBuf; #[test] fn join_works() { let mut path = RelativePathBuf(vec![]).join("some".to_owned()); assert_eq!(path.0.len(), 1); assert_eq!(path.0[0], "some"); path = path.join("dir".to_owned()); assert_eq!(path.0.len(), 2); assert_eq!(path.0[0], "some"); assert_eq!(path.0[1], "dir"); } #[test] fn from_components_works() { let path = RelativePathBuf::from_components(vec!["some".to_owned(), "dir".to_owned()].into_iter()); assert_eq!(path.0.len(), 2); assert_eq!(path.0[0], "some"); assert_eq!(path.0[1], "dir"); } #[test] fn from_str_works() { { let path: RelativePathBuf = "some/dir".into(); assert_eq!(path.0.len(), 2); assert_eq!(path.0[0], "some"); assert_eq!(path.0[1], "dir"); } { let path: RelativePathBuf = "some".into(); assert_eq!(path.0.len(), 1); assert_eq!(path.0[0], "some"); } { let path: RelativePathBuf = "".into(); assert_eq!(path.0.len(), 0); } { let path: RelativePathBuf = "/some//dir/".into(); assert_eq!(path.0.len(), 2); assert_eq!(path.0[0], "some"); assert_eq!(path.0[1], "dir"); } } }