1use std::path::{Component, Path, PathBuf};
2
3pub trait PathExt {
4 fn rem(&self, p: impl AsRef<Path>) -> Option<PathBuf>;
5}
6
7impl PathExt for Path {
8 fn rem(&self, p: impl AsRef<Path>) -> Option<PathBuf> {
9 let left: Vec<Component> = self.components().collect();
10 let right: Vec<Component> = p.as_ref().components().collect();
11 let max_length = left.len().min(right.len());
12 for index in (1..=max_length).rev() {
13 if left[left.len() - index..] == right[..index] {
14 let mut path_buf = PathBuf::new();
15 for component in &right[index..] {
16 path_buf.push(component);
17 }
18 return Some(path_buf);
19 }
20 }
21 None
22 }
23}
24
25pub fn sleep(millis: u64) {
27 if millis > 0 {
28 std::thread::sleep(std::time::Duration::from_millis(millis));
29 }
30}
31
32#[cfg(test)]
33mod tests {
34 use super::*;
35
36 #[test]
37 fn _0001() {
38 let p = Path::new("/a/b/c/d");
39 let s = Path::new("e/f");
40 assert_eq!(None, p.rem(s));
41 }
42
43 #[test]
44 fn _0002() {
45 let p = Path::new("/a/b/c/d");
46 let s = Path::new("d/e/f");
47 assert_eq!("e/f", p.rem(s).unwrap().to_string_lossy());
48 }
49
50 #[test]
51 fn _0003() {
52 let p = Path::new("a/b/c/d/e");
53 let s = Path::new("d/e/f");
54 assert_eq!("f", p.rem(s).unwrap().to_string_lossy());
55 }
56
57 #[test]
58 fn _0004() {
59 let p = Path::new("a/b/c");
60 let s = Path::new("e/f");
61 assert_eq!(None, p.rem(s));
62 }
63
64 #[test]
65 fn _0005() {
66 let p = Path::new("a/b/c");
67 let s = Path::new("a/b/c");
68 assert_eq!("", p.rem(s).unwrap().to_string_lossy());
69 }
70
71 #[test]
72 fn _0006() {
73 let p = Path::new("a/b/c");
74 let s = Path::new("b/c/d");
75 assert_eq!("d", p.rem(s).unwrap().to_string_lossy());
76 }
77}