Show More
@@ -112,6 +112,9 b' impl HgPath {' | |||
|
112 | 112 | pub fn contains(&self, other: u8) -> bool { |
|
113 | 113 | self.inner.contains(&other) |
|
114 | 114 | } |
|
115 | pub fn starts_with(&self, needle: impl AsRef<HgPath>) -> bool { | |
|
116 | self.inner.starts_with(needle.as_ref().as_bytes()) | |
|
117 | } | |
|
115 | 118 | pub fn join<T: ?Sized + AsRef<HgPath>>(&self, other: &T) -> HgPathBuf { |
|
116 | 119 | let mut inner = self.inner.to_owned(); |
|
117 | 120 | if inner.len() != 0 && inner.last() != Some(&b'/') { |
@@ -120,6 +123,21 b' impl HgPath {' | |||
|
120 | 123 | inner.extend(other.as_ref().bytes()); |
|
121 | 124 | HgPathBuf::from_bytes(&inner) |
|
122 | 125 | } |
|
126 | /// Given a base directory, returns the slice of `self` relative to the | |
|
127 | /// base directory. If `base` is not a directory (does not end with a | |
|
128 | /// `b'/'`), returns `None`. | |
|
129 | pub fn relative_to(&self, base: impl AsRef<HgPath>) -> Option<&HgPath> { | |
|
130 | let base = base.as_ref(); | |
|
131 | if base.is_empty() { | |
|
132 | return Some(self); | |
|
133 | } | |
|
134 | let is_dir = base.as_bytes().ends_with(b"/"); | |
|
135 | if is_dir && self.starts_with(base) { | |
|
136 | Some(HgPath::new(&self.inner[base.len()..])) | |
|
137 | } else { | |
|
138 | None | |
|
139 | } | |
|
140 | } | |
|
123 | 141 | /// Checks for errors in the path, short-circuiting at the first one. |
|
124 | 142 | /// This generates fine-grained errors useful for debugging. |
|
125 | 143 | /// To simply check if the path is valid during tests, use `is_valid`. |
@@ -412,4 +430,35 b' mod tests {' | |||
|
412 | 430 | let path = HgPathBuf::from_bytes(b"a").join(HgPath::new(b"/b")); |
|
413 | 431 | assert_eq!(b"a//b", path.as_bytes()); |
|
414 | 432 | } |
|
433 | ||
|
434 | #[test] | |
|
435 | fn test_relative_to() { | |
|
436 | let path = HgPath::new(b""); | |
|
437 | let base = HgPath::new(b""); | |
|
438 | assert_eq!(Some(path), path.relative_to(base)); | |
|
439 | ||
|
440 | let path = HgPath::new(b"path"); | |
|
441 | let base = HgPath::new(b""); | |
|
442 | assert_eq!(Some(path), path.relative_to(base)); | |
|
443 | ||
|
444 | let path = HgPath::new(b"a"); | |
|
445 | let base = HgPath::new(b"b"); | |
|
446 | assert_eq!(None, path.relative_to(base)); | |
|
447 | ||
|
448 | let path = HgPath::new(b"a/b"); | |
|
449 | let base = HgPath::new(b"a"); | |
|
450 | assert_eq!(None, path.relative_to(base)); | |
|
451 | ||
|
452 | let path = HgPath::new(b"a/b"); | |
|
453 | let base = HgPath::new(b"a/"); | |
|
454 | assert_eq!(Some(HgPath::new(b"b")), path.relative_to(base)); | |
|
455 | ||
|
456 | let path = HgPath::new(b"nested/path/to/b"); | |
|
457 | let base = HgPath::new(b"nested/path/"); | |
|
458 | assert_eq!(Some(HgPath::new(b"to/b")), path.relative_to(base)); | |
|
459 | ||
|
460 | let path = HgPath::new(b"ends/with/dir/"); | |
|
461 | let base = HgPath::new(b"ends/"); | |
|
462 | assert_eq!(Some(HgPath::new(b"with/dir/")), path.relative_to(base)); | |
|
463 | } | |
|
415 | 464 | } |
General Comments 0
You need to be logged in to leave comments.
Login now