Mercurial > public > mercurial-scm > hg
comparison rust/hg-core/src/utils/hg_path.rs @ 43833:4f1543a2f5c3
rust-hg-path: add method to get part of a path relative to a prefix
This will be used in the next patch in this series.
Differential Revision: https://phab.mercurial-scm.org/D7526
author | Rapha?l Gom?s <rgomes@octobus.net> |
---|---|
date | Fri, 29 Nov 2019 17:24:40 +0100 |
parents | c27e688fcdc3 |
children | 4b3c8df189bc |
comparison
equal
deleted
inserted
replaced
43832:1bb4e9b02984 | 43833:4f1543a2f5c3 |
---|---|
110 &self.inner | 110 &self.inner |
111 } | 111 } |
112 pub fn contains(&self, other: u8) -> bool { | 112 pub fn contains(&self, other: u8) -> bool { |
113 self.inner.contains(&other) | 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 pub fn join<T: ?Sized + AsRef<HgPath>>(&self, other: &T) -> HgPathBuf { | 118 pub fn join<T: ?Sized + AsRef<HgPath>>(&self, other: &T) -> HgPathBuf { |
116 let mut inner = self.inner.to_owned(); | 119 let mut inner = self.inner.to_owned(); |
117 if inner.len() != 0 && inner.last() != Some(&b'/') { | 120 if inner.len() != 0 && inner.last() != Some(&b'/') { |
118 inner.push(b'/'); | 121 inner.push(b'/'); |
119 } | 122 } |
120 inner.extend(other.as_ref().bytes()); | 123 inner.extend(other.as_ref().bytes()); |
121 HgPathBuf::from_bytes(&inner) | 124 HgPathBuf::from_bytes(&inner) |
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 } | |
122 } | 140 } |
123 /// Checks for errors in the path, short-circuiting at the first one. | 141 /// Checks for errors in the path, short-circuiting at the first one. |
124 /// This generates fine-grained errors useful for debugging. | 142 /// This generates fine-grained errors useful for debugging. |
125 /// To simply check if the path is valid during tests, use `is_valid`. | 143 /// To simply check if the path is valid during tests, use `is_valid`. |
126 pub fn check_state(&self) -> Result<(), HgPathError> { | 144 pub fn check_state(&self) -> Result<(), HgPathError> { |
410 let path = HgPathBuf::from_bytes(b"a/").join(HgPath::new(b"/b")); | 428 let path = HgPathBuf::from_bytes(b"a/").join(HgPath::new(b"/b")); |
411 assert_eq!(b"a//b", path.as_bytes()); | 429 assert_eq!(b"a//b", path.as_bytes()); |
412 let path = HgPathBuf::from_bytes(b"a").join(HgPath::new(b"/b")); | 430 let path = HgPathBuf::from_bytes(b"a").join(HgPath::new(b"/b")); |
413 assert_eq!(b"a//b", path.as_bytes()); | 431 assert_eq!(b"a//b", path.as_bytes()); |
414 } | 432 } |
415 } | 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 } | |
464 } |