D7867: rust-hg-path: add useful methods to `HgPath`
Closed by commit rHGe1ba9c5d5e78: rust-hg-path: add useful methods to `HgPath` (authored by Alphare). This revision was automatically updated to reflect the committed changes. This revision was not accepted when it landed; it landed in state "Needs Review". REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D7867?vs=19935=19956 CHANGES SINCE LAST ACTION https://phab.mercurial-scm.org/D7867/new/ REVISION DETAIL https://phab.mercurial-scm.org/D7867 AFFECTED FILES rust/Cargo.lock rust/hg-core/Cargo.toml rust/hg-core/src/utils/hg_path.rs CHANGE DETAILS diff --git a/rust/hg-core/src/utils/hg_path.rs b/rust/hg-core/src/utils/hg_path.rs --- a/rust/hg-core/src/utils/hg_path.rs +++ b/rust/hg-core/src/utils/hg_path.rs @@ -173,10 +173,17 @@ pub fn contains(, other: u8) -> bool { self.inner.contains() } -pub fn starts_with(, needle: impl AsRef) -> bool { +pub fn starts_with(, needle: impl AsRef) -> bool { self.inner.starts_with(needle.as_ref().as_bytes()) } -pub fn join>(, other: ) -> HgPathBuf { +pub fn trim_trailing_slash() -> { +Self::new(if self.inner.last() == Some('/') { +[..self.inner.len() - 1] +} else { +[..] +}) +} +pub fn join>(, other: ) -> HgPathBuf { let mut inner = self.inner.to_owned(); if inner.len() != 0 && inner.last() != Some('/') { inner.push(b'/'); @@ -184,17 +191,24 @@ inner.extend(other.as_ref().bytes()); HgPathBuf::from_bytes() } +pub fn parent() -> { +let inner = self.as_bytes(); +HgPath::new(match inner.iter().rposition(|b| *b == b'/') { +Some(pos) => [..pos], +None => &[], +}) +} /// Given a base directory, returns the slice of `self` relative to the /// base directory. If `base` is not a directory (does not end with a /// `b'/'`), returns `None`. -pub fn relative_to(, base: impl AsRef) -> Option<> { +pub fn relative_to(, base: impl AsRef) -> Option<> { let base = base.as_ref(); if base.is_empty() { return Some(self); } let is_dir = base.as_bytes().ends_with(b"/"); if is_dir && self.starts_with(base) { -Some(HgPath::new([base.len()..])) +Some(Self::new([base.len()..])) } else { None } @@ -484,6 +498,7 @@ #[cfg(test)] mod tests { use super::*; +use pretty_assertions::assert_eq; #[test] fn test_path_states() { @@ -712,4 +727,19 @@ ) ); } + +#[test] +fn test_parent() { +let path = HgPath::new(b""); +assert_eq!(path.parent(), path); + +let path = HgPath::new(b"a"); +assert_eq!(path.parent(), HgPath::new(b"")); + +let path = HgPath::new(b"a/b"); +assert_eq!(path.parent(), HgPath::new(b"a")); + +let path = HgPath::new(b"a/other/b"); +assert_eq!(path.parent(), HgPath::new(b"a/other")); +} } diff --git a/rust/hg-core/Cargo.toml b/rust/hg-core/Cargo.toml --- a/rust/hg-core/Cargo.toml +++ b/rust/hg-core/Cargo.toml @@ -20,4 +20,5 @@ twox-hash = "1.5.0" [dev-dependencies] -tempfile = "3.1.0" \ No newline at end of file +tempfile = "3.1.0" +pretty_assertions = "0.6.1" \ No newline at end of file diff --git a/rust/Cargo.lock b/rust/Cargo.lock --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -2,13 +2,21 @@ # It is not intended for manual editing. [[package]] name = "aho-corasick" -version = "0.7.7" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index; dependencies = [ "memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] +name = "ansi_term" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index; +dependencies = [ + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] name = "autocfg" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index; @@ -51,13 +59,13 @@ [[package]] name = "cpython" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index; dependencies = [ "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "python27-sys 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "python3-sys 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "python27-sys 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "python3-sys 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -102,6 +110,20 @@ ] [[package]] +name = "ctor" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index; +dependencies = [ + "quote 1.0.2
D7867: rust-hg-path: add useful methods to `HgPath`
martinvonz added inline comments. INLINE COMMENTS > hg_path.rs:195 > +pub fn parent() -> { > +let inner = self.as_bytes(); > +HgPath::new(match inner.iter().rposition(|b| *b == b'/') { Might be good to add an `assert!` here in case my assertion (that `HgPath` should never have a trailing `/`) is not correct. REPOSITORY rHG Mercurial CHANGES SINCE LAST ACTION https://phab.mercurial-scm.org/D7867/new/ REVISION DETAIL https://phab.mercurial-scm.org/D7867 To: Alphare, #hg-reviewers, kevincox, pulkit, martinvonz Cc: martinvonz, durin42, kevincox, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D7867: rust-hg-path: add useful methods to `HgPath`
Alphare updated this revision to Diff 19935. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D7867?vs=19382=19935 BRANCH default CHANGES SINCE LAST ACTION https://phab.mercurial-scm.org/D7867/new/ REVISION DETAIL https://phab.mercurial-scm.org/D7867 AFFECTED FILES rust/Cargo.lock rust/hg-core/Cargo.toml rust/hg-core/src/utils/hg_path.rs CHANGE DETAILS diff --git a/rust/hg-core/src/utils/hg_path.rs b/rust/hg-core/src/utils/hg_path.rs --- a/rust/hg-core/src/utils/hg_path.rs +++ b/rust/hg-core/src/utils/hg_path.rs @@ -173,10 +173,17 @@ pub fn contains(, other: u8) -> bool { self.inner.contains() } -pub fn starts_with(, needle: impl AsRef) -> bool { +pub fn starts_with(, needle: impl AsRef) -> bool { self.inner.starts_with(needle.as_ref().as_bytes()) } -pub fn join>(, other: ) -> HgPathBuf { +pub fn trim_trailing_slash() -> { +Self::new(if self.inner.last() == Some('/') { +[..self.inner.len() - 1] +} else { +[..] +}) +} +pub fn join>(, other: ) -> HgPathBuf { let mut inner = self.inner.to_owned(); if inner.len() != 0 && inner.last() != Some('/') { inner.push(b'/'); @@ -184,17 +191,24 @@ inner.extend(other.as_ref().bytes()); HgPathBuf::from_bytes() } +pub fn parent() -> { +let inner = self.as_bytes(); +HgPath::new(match inner.iter().rposition(|b| *b == b'/') { +Some(pos) => [..pos], +None => &[], +}) +} /// Given a base directory, returns the slice of `self` relative to the /// base directory. If `base` is not a directory (does not end with a /// `b'/'`), returns `None`. -pub fn relative_to(, base: impl AsRef) -> Option<> { +pub fn relative_to(, base: impl AsRef) -> Option<> { let base = base.as_ref(); if base.is_empty() { return Some(self); } let is_dir = base.as_bytes().ends_with(b"/"); if is_dir && self.starts_with(base) { -Some(HgPath::new([base.len()..])) +Some(Self::new([base.len()..])) } else { None } @@ -484,6 +498,7 @@ #[cfg(test)] mod tests { use super::*; +use pretty_assertions::assert_eq; #[test] fn test_path_states() { @@ -712,4 +727,19 @@ ) ); } + +#[test] +fn test_parent() { +let path = HgPath::new(b""); +assert_eq!(path.parent(), path); + +let path = HgPath::new(b"a"); +assert_eq!(path.parent(), HgPath::new(b"")); + +let path = HgPath::new(b"a/b"); +assert_eq!(path.parent(), HgPath::new(b"a")); + +let path = HgPath::new(b"a/other/b"); +assert_eq!(path.parent(), HgPath::new(b"a/other")); +} } diff --git a/rust/hg-core/Cargo.toml b/rust/hg-core/Cargo.toml --- a/rust/hg-core/Cargo.toml +++ b/rust/hg-core/Cargo.toml @@ -20,4 +20,5 @@ twox-hash = "1.5.0" [dev-dependencies] -tempfile = "3.1.0" \ No newline at end of file +tempfile = "3.1.0" +pretty_assertions = "0.6.1" \ No newline at end of file diff --git a/rust/Cargo.lock b/rust/Cargo.lock --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -2,13 +2,21 @@ # It is not intended for manual editing. [[package]] name = "aho-corasick" -version = "0.7.7" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index; dependencies = [ "memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] +name = "ansi_term" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index; +dependencies = [ + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] name = "autocfg" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index; @@ -51,13 +59,13 @@ [[package]] name = "cpython" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index; dependencies = [ "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "python27-sys 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "python3-sys 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "python27-sys 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "python3-sys 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -102,6 +110,20 @@ ] [[package]] +name = "ctor" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index; +dependencies = [ + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "difference" +version = "2.0.0" +source =
D7867: rust-hg-path: add useful methods to `HgPath`
Alphare added inline comments. INLINE COMMENTS > martinvonz wrote in hg_path.rs:173 > And what happens if you remove it? It only breaks the single rust test I had to check for that particular case. I'll remove it. REPOSITORY rHG Mercurial CHANGES SINCE LAST ACTION https://phab.mercurial-scm.org/D7867/new/ REVISION DETAIL https://phab.mercurial-scm.org/D7867 To: Alphare, #hg-reviewers, kevincox, pulkit, martinvonz Cc: martinvonz, durin42, kevincox, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D7867: rust-hg-path: add useful methods to `HgPath`
martinvonz added inline comments. INLINE COMMENTS > Alphare wrote in hg_path.rs:173 > This is currently this only place it's called (line 189), it was refactored > for readability first I suppose. And what happens if you remove it? REPOSITORY rHG Mercurial BRANCH default CHANGES SINCE LAST ACTION https://phab.mercurial-scm.org/D7867/new/ REVISION DETAIL https://phab.mercurial-scm.org/D7867 To: Alphare, #hg-reviewers, kevincox, pulkit Cc: martinvonz, durin42, kevincox, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D7867: rust-hg-path: add useful methods to `HgPath`
Alphare added inline comments. INLINE COMMENTS > martinvonz wrote in hg_path.rs:173 > Another way of thinking about my question: what happens if we never call this > function? Which tests fail? This is currently this only place it's called (line 189), it was refactored for readability first I suppose. REPOSITORY rHG Mercurial BRANCH default CHANGES SINCE LAST ACTION https://phab.mercurial-scm.org/D7867/new/ REVISION DETAIL https://phab.mercurial-scm.org/D7867 To: Alphare, #hg-reviewers, kevincox, pulkit Cc: martinvonz, durin42, kevincox, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D7867: rust-hg-path: add useful methods to `HgPath`
martinvonz added inline comments. INLINE COMMENTS > Alphare wrote in hg_path.rs:173 > Maybe, but I'm not sure it's worth risking a weird edge-case bug or losing > performance over (possibly negligible). What do you think? Another way of thinking about my question: what happens if we never call this function? Which tests fail? REPOSITORY rHG Mercurial BRANCH default CHANGES SINCE LAST ACTION https://phab.mercurial-scm.org/D7867/new/ REVISION DETAIL https://phab.mercurial-scm.org/D7867 To: Alphare, #hg-reviewers, kevincox, pulkit Cc: martinvonz, durin42, kevincox, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D7867: rust-hg-path: add useful methods to `HgPath`
Alphare added inline comments. INLINE COMMENTS > martinvonz wrote in hg_path.rs:173 > When do we create such paths? I can imagine using them for referring to > directories. Is that it? If it's some other use-case, I wonder if we can > instead prevent the trailing slash from entering the `HgPath`. Maybe, but I'm not sure it's worth risking a weird edge-case bug or losing performance over (possibly negligible). What do you think? REPOSITORY rHG Mercurial BRANCH default CHANGES SINCE LAST ACTION https://phab.mercurial-scm.org/D7867/new/ REVISION DETAIL https://phab.mercurial-scm.org/D7867 To: Alphare, #hg-reviewers, kevincox, pulkit Cc: martinvonz, durin42, kevincox, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D7867: rust-hg-path: add useful methods to `HgPath`
martinvonz added inline comments. INLINE COMMENTS > hg_path.rs:173 > } > -pub fn join>(, other: ) -> HgPathBuf { > +pub fn trim_trailing_slash() -> { > +Self::new(if self.inner.last() == Some('/') { When do we create such paths? I can imagine using them for referring to directories. Is that it? If it's some other use-case, I wonder if we can instead prevent the trailing slash from entering the `HgPath`. REPOSITORY rHG Mercurial BRANCH default CHANGES SINCE LAST ACTION https://phab.mercurial-scm.org/D7867/new/ REVISION DETAIL https://phab.mercurial-scm.org/D7867 To: Alphare, #hg-reviewers, kevincox, pulkit Cc: martinvonz, durin42, kevincox, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D7867: rust-hg-path: add useful methods to `HgPath`
Alphare updated this revision to Diff 19382. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D7867?vs=19352=19382 BRANCH default CHANGES SINCE LAST ACTION https://phab.mercurial-scm.org/D7867/new/ REVISION DETAIL https://phab.mercurial-scm.org/D7867 AFFECTED FILES rust/Cargo.lock rust/hg-core/Cargo.toml rust/hg-core/src/utils/hg_path.rs CHANGE DETAILS diff --git a/rust/hg-core/src/utils/hg_path.rs b/rust/hg-core/src/utils/hg_path.rs --- a/rust/hg-core/src/utils/hg_path.rs +++ b/rust/hg-core/src/utils/hg_path.rs @@ -167,10 +167,17 @@ pub fn contains(, other: u8) -> bool { self.inner.contains() } -pub fn starts_with(, needle: impl AsRef) -> bool { +pub fn starts_with(, needle: impl AsRef) -> bool { self.inner.starts_with(needle.as_ref().as_bytes()) } -pub fn join>(, other: ) -> HgPathBuf { +pub fn trim_trailing_slash() -> { +Self::new(if self.inner.last() == Some('/') { +[..self.inner.len() - 1] +} else { +[..] +}) +} +pub fn join>(, other: ) -> HgPathBuf { let mut inner = self.inner.to_owned(); if inner.len() != 0 && inner.last() != Some('/') { inner.push(b'/'); @@ -178,17 +185,24 @@ inner.extend(other.as_ref().bytes()); HgPathBuf::from_bytes() } +pub fn parent() -> { +let inner = self.trim_trailing_slash().as_bytes(); +HgPath::new(match inner.iter().rposition(|b| *b == b'/') { +Some(pos) => [..pos], +None => &[], +}) +} /// Given a base directory, returns the slice of `self` relative to the /// base directory. If `base` is not a directory (does not end with a /// `b'/'`), returns `None`. -pub fn relative_to(, base: impl AsRef) -> Option<> { +pub fn relative_to(, base: impl AsRef) -> Option<> { let base = base.as_ref(); if base.is_empty() { return Some(self); } let is_dir = base.as_bytes().ends_with(b"/"); if is_dir && self.starts_with(base) { -Some(HgPath::new([base.len()..])) +Some(Self::new([base.len()..])) } else { None } @@ -476,6 +490,7 @@ #[cfg(test)] mod tests { use super::*; +use pretty_assertions::assert_eq; #[test] fn test_path_states() { @@ -704,4 +719,19 @@ ) ); } + +#[test] +fn test_parent() { +let path = HgPath::new(b""); +assert_eq!(path.parent(), path); + +let path = HgPath::new(b"a/"); +assert_eq!(path.parent(), HgPath::new(b"")); + +let path = HgPath::new(b"a/b"); +assert_eq!(path.parent(), HgPath::new(b"a")); + +let path = HgPath::new(b"a/other/b"); +assert_eq!(path.parent(), HgPath::new(b"a/other")); +} } diff --git a/rust/hg-core/Cargo.toml b/rust/hg-core/Cargo.toml --- a/rust/hg-core/Cargo.toml +++ b/rust/hg-core/Cargo.toml @@ -19,4 +19,5 @@ twox-hash = "1.5.0" [dev-dependencies] -tempfile = "3.1.0" \ No newline at end of file +tempfile = "3.1.0" +pretty_assertions = "0.6.1" \ No newline at end of file diff --git a/rust/Cargo.lock b/rust/Cargo.lock --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -9,6 +9,14 @@ ] [[package]] +name = "ansi_term" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index; +dependencies = [ + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] name = "arrayvec" version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index; @@ -104,6 +112,20 @@ ] [[package]] +name = "ctor" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index; +dependencies = [ + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "difference" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index; + +[[package]] name = "either" version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index; @@ -130,6 +152,7 @@ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -200,11 +223,38 @@ ] [[package]] +name = "output_vt100" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index; +dependencies = [ + "winapi 0.3.8
D7867: rust-hg-path: add useful methods to `HgPath`
Alphare added inline comments. INLINE COMMENTS > kevincox wrote in hg_path.rs:169 > I don't think we should have this method. It provides us no way to ensure > that the invariants of this type are upheld. It is slightly more typing but I > think we should recommend converting to a slice, doing the mutation, then > converting back to `HgPath` then we can at least to validation (possibly only > in debug builds) in the constructor. Fair enough. REPOSITORY rHG Mercurial CHANGES SINCE LAST ACTION https://phab.mercurial-scm.org/D7867/new/ REVISION DETAIL https://phab.mercurial-scm.org/D7867 To: Alphare, #hg-reviewers, kevincox Cc: durin42, kevincox, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D7867: rust-hg-path: add useful methods to `HgPath`
This revision now requires changes to proceed. kevincox added inline comments. kevincox requested changes to this revision. INLINE COMMENTS > hg_path.rs:169 > + self.inner > +} > pub fn contains(, other: u8) -> bool { I don't think we should have this method. It provides us no way to ensure that the invariants of this type are upheld. It is slightly more typing but I think we should recommend converting to a slice, doing the mutation, then converting back to `HgPath` then we can at least to validation (possibly only in debug builds) in the constructor. REPOSITORY rHG Mercurial CHANGES SINCE LAST ACTION https://phab.mercurial-scm.org/D7867/new/ REVISION DETAIL https://phab.mercurial-scm.org/D7867 To: Alphare, #hg-reviewers, kevincox Cc: durin42, kevincox, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D7867: rust-hg-path: add useful methods to `HgPath`
Alphare updated this revision to Diff 19352. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D7867?vs=19318=19352 BRANCH default CHANGES SINCE LAST ACTION https://phab.mercurial-scm.org/D7867/new/ REVISION DETAIL https://phab.mercurial-scm.org/D7867 AFFECTED FILES rust/Cargo.lock rust/hg-core/Cargo.toml rust/hg-core/src/utils/hg_path.rs CHANGE DETAILS diff --git a/rust/hg-core/src/utils/hg_path.rs b/rust/hg-core/src/utils/hg_path.rs --- a/rust/hg-core/src/utils/hg_path.rs +++ b/rust/hg-core/src/utils/hg_path.rs @@ -164,13 +164,23 @@ pub fn as_bytes() -> &[u8] { } +pub fn as_bytes_mut( self) -> [u8] { + self.inner +} pub fn contains(, other: u8) -> bool { self.inner.contains() } -pub fn starts_with(, needle: impl AsRef) -> bool { +pub fn starts_with(, needle: impl AsRef) -> bool { self.inner.starts_with(needle.as_ref().as_bytes()) } -pub fn join>(, other: ) -> HgPathBuf { +pub fn trim_trailing_slash() -> { +Self::new(if self.inner.last() == Some('/') { +[..self.inner.len() - 1] +} else { +[..] +}) +} +pub fn join>(, other: ) -> HgPathBuf { let mut inner = self.inner.to_owned(); if inner.len() != 0 && inner.last() != Some('/') { inner.push(b'/'); @@ -178,17 +188,24 @@ inner.extend(other.as_ref().bytes()); HgPathBuf::from_bytes() } +pub fn parent() -> { +let inner = self.trim_trailing_slash().as_bytes(); +HgPath::new(match inner.iter().rposition(|b| *b == b'/') { +Some(pos) => [..pos], +None => &[], +}) +} /// Given a base directory, returns the slice of `self` relative to the /// base directory. If `base` is not a directory (does not end with a /// `b'/'`), returns `None`. -pub fn relative_to(, base: impl AsRef) -> Option<> { +pub fn relative_to(, base: impl AsRef) -> Option<> { let base = base.as_ref(); if base.is_empty() { return Some(self); } let is_dir = base.as_bytes().ends_with(b"/"); if is_dir && self.starts_with(base) { -Some(HgPath::new([base.len()..])) +Some(Self::new([base.len()..])) } else { None } @@ -476,6 +493,7 @@ #[cfg(test)] mod tests { use super::*; +use pretty_assertions::assert_eq; #[test] fn test_path_states() { @@ -704,4 +722,19 @@ ) ); } + +#[test] +fn test_parent() { +let path = HgPath::new(b""); +assert_eq!(path.parent(), path); + +let path = HgPath::new(b"a/"); +assert_eq!(path.parent(), HgPath::new(b"")); + +let path = HgPath::new(b"a/b"); +assert_eq!(path.parent(), HgPath::new(b"a")); + +let path = HgPath::new(b"a/other/b"); +assert_eq!(path.parent(), HgPath::new(b"a/other")); +} } diff --git a/rust/hg-core/Cargo.toml b/rust/hg-core/Cargo.toml --- a/rust/hg-core/Cargo.toml +++ b/rust/hg-core/Cargo.toml @@ -19,4 +19,5 @@ twox-hash = "1.5.0" [dev-dependencies] -tempfile = "3.1.0" \ No newline at end of file +tempfile = "3.1.0" +pretty_assertions = "0.6.1" \ No newline at end of file diff --git a/rust/Cargo.lock b/rust/Cargo.lock --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -9,6 +9,14 @@ ] [[package]] +name = "ansi_term" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index; +dependencies = [ + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] name = "arrayvec" version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index; @@ -104,6 +112,20 @@ ] [[package]] +name = "ctor" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index; +dependencies = [ + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "difference" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index; + +[[package]] name = "either" version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index; @@ -130,6 +152,7 @@ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -200,11 +223,38 @@ ] [[package]] +name = "output_vt100" +version = "0.1.2" +source =
D7867: rust-hg-path: add useful methods to `HgPath`
Alphare updated this revision to Diff 19318. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D7867?vs=19259=19318 BRANCH default CHANGES SINCE LAST ACTION https://phab.mercurial-scm.org/D7867/new/ REVISION DETAIL https://phab.mercurial-scm.org/D7867 AFFECTED FILES rust/Cargo.lock rust/hg-core/Cargo.toml rust/hg-core/src/utils/hg_path.rs CHANGE DETAILS diff --git a/rust/hg-core/src/utils/hg_path.rs b/rust/hg-core/src/utils/hg_path.rs --- a/rust/hg-core/src/utils/hg_path.rs +++ b/rust/hg-core/src/utils/hg_path.rs @@ -164,13 +164,23 @@ pub fn as_bytes() -> &[u8] { } +pub fn as_bytes_mut( self) -> [u8] { + self.inner +} pub fn contains(, other: u8) -> bool { self.inner.contains() } -pub fn starts_with(, needle: impl AsRef) -> bool { +pub fn starts_with(, needle: impl AsRef) -> bool { self.inner.starts_with(needle.as_ref().as_bytes()) } -pub fn join>(, other: ) -> HgPathBuf { +pub fn trim_trailing_slash() -> { +Self::new(if self.inner.last() == Some('/') { +[..self.inner.len() - 1] +} else { +[..] +}) +} +pub fn join>(, other: ) -> HgPathBuf { let mut inner = self.inner.to_owned(); if inner.len() != 0 && inner.last() != Some('/') { inner.push(b'/'); @@ -178,17 +188,24 @@ inner.extend(other.as_ref().bytes()); HgPathBuf::from_bytes() } +pub fn parent() -> { +let inner = self.trim_trailing_slash().as_bytes(); +HgPath::new(match inner.iter().rposition(|b| *b == b'/') { +Some(pos) => [..pos], +None => &[], +}) +} /// Given a base directory, returns the slice of `self` relative to the /// base directory. If `base` is not a directory (does not end with a /// `b'/'`), returns `None`. -pub fn relative_to(, base: impl AsRef) -> Option<> { +pub fn relative_to(, base: impl AsRef) -> Option<> { let base = base.as_ref(); if base.is_empty() { return Some(self); } let is_dir = base.as_bytes().ends_with(b"/"); if is_dir && self.starts_with(base) { -Some(HgPath::new([base.len()..])) +Some(Self::new([base.len()..])) } else { None } @@ -403,6 +420,7 @@ #[cfg(test)] mod tests { use super::*; +use pretty_assertions::assert_eq; #[test] fn test_path_states() { @@ -534,4 +552,19 @@ let base = HgPath::new(b"ends/"); assert_eq!(Some(HgPath::new(b"with/dir/")), path.relative_to(base)); } + +#[test] +fn test_parent() { +let path = HgPath::new(b""); +assert_eq!(path.parent(), path); + +let path = HgPath::new(b"a/"); +assert_eq!(path.parent(), HgPath::new(b"")); + +let path = HgPath::new(b"a/b"); +assert_eq!(path.parent(), HgPath::new(b"a")); + +let path = HgPath::new(b"a/other/b"); +assert_eq!(path.parent(), HgPath::new(b"a/other")); +} } diff --git a/rust/hg-core/Cargo.toml b/rust/hg-core/Cargo.toml --- a/rust/hg-core/Cargo.toml +++ b/rust/hg-core/Cargo.toml @@ -19,4 +19,5 @@ twox-hash = "1.5.0" [dev-dependencies] -tempfile = "3.1.0" \ No newline at end of file +tempfile = "3.1.0" +pretty_assertions = "0.6.1" \ No newline at end of file diff --git a/rust/Cargo.lock b/rust/Cargo.lock --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -9,6 +9,14 @@ ] [[package]] +name = "ansi_term" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index; +dependencies = [ + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] name = "arrayvec" version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index; @@ -104,6 +112,20 @@ ] [[package]] +name = "ctor" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index; +dependencies = [ + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "difference" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index; + +[[package]] name = "either" version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index; @@ -130,6 +152,7 @@ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -200,11 +223,38
D7867: rust-hg-path: add useful methods to `HgPath`
kevincox added inline comments. kevincox accepted this revision. INLINE COMMENTS > hg_path.rs:189 > +[..] > +}; > +HgPath::new(match inner.iter().rposition(|b| *b == b'/') { It would be nice to have a `trim_trailing_slash` helper. REPOSITORY rHG Mercurial CHANGES SINCE LAST ACTION https://phab.mercurial-scm.org/D7867/new/ REVISION DETAIL https://phab.mercurial-scm.org/D7867 To: Alphare, #hg-reviewers, kevincox Cc: durin42, kevincox, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D7867: rust-hg-path: add useful methods to `HgPath`
Alphare created this revision. Herald added subscribers: mercurial-devel, kevincox, durin42. Herald added a reviewer: hg-reviewers. REVISION SUMMARY This changeset introduces the use of the `pretty_assertions` crate for easier to read test output. REPOSITORY rHG Mercurial BRANCH default REVISION DETAIL https://phab.mercurial-scm.org/D7867 AFFECTED FILES rust/Cargo.lock rust/hg-core/Cargo.toml rust/hg-core/src/utils/hg_path.rs CHANGE DETAILS diff --git a/rust/hg-core/src/utils/hg_path.rs b/rust/hg-core/src/utils/hg_path.rs --- a/rust/hg-core/src/utils/hg_path.rs +++ b/rust/hg-core/src/utils/hg_path.rs @@ -164,13 +164,16 @@ pub fn as_bytes() -> &[u8] { } +pub fn as_bytes_mut( self) -> [u8] { + self.inner +} pub fn contains(, other: u8) -> bool { self.inner.contains() } -pub fn starts_with(, needle: impl AsRef) -> bool { +pub fn starts_with(, needle: impl AsRef) -> bool { self.inner.starts_with(needle.as_ref().as_bytes()) } -pub fn join>(, other: ) -> HgPathBuf { +pub fn join>(, other: ) -> HgPathBuf { let mut inner = self.inner.to_owned(); if inner.len() != 0 && inner.last() != Some('/') { inner.push(b'/'); @@ -178,17 +181,28 @@ inner.extend(other.as_ref().bytes()); HgPathBuf::from_bytes() } +pub fn parent() -> { +let inner = if self.inner.last() == Some('/') { +[..self.inner.len() - 1] +} else { +[..] +}; +HgPath::new(match inner.iter().rposition(|b| *b == b'/') { +Some(pos) => [..pos], +None => &[], +}) +} /// Given a base directory, returns the slice of `self` relative to the /// base directory. If `base` is not a directory (does not end with a /// `b'/'`), returns `None`. -pub fn relative_to(, base: impl AsRef) -> Option<> { +pub fn relative_to(, base: impl AsRef) -> Option<> { let base = base.as_ref(); if base.is_empty() { return Some(self); } let is_dir = base.as_bytes().ends_with(b"/"); if is_dir && self.starts_with(base) { -Some(HgPath::new([base.len()..])) +Some(Self::new([base.len()..])) } else { None } @@ -403,6 +417,7 @@ #[cfg(test)] mod tests { use super::*; +use pretty_assertions::assert_eq; #[test] fn test_path_states() { @@ -534,4 +549,19 @@ let base = HgPath::new(b"ends/"); assert_eq!(Some(HgPath::new(b"with/dir/")), path.relative_to(base)); } + +#[test] +fn test_parent() { +let path = HgPath::new(b""); +assert_eq!(path.parent(), path); + +let path = HgPath::new(b"a/"); +assert_eq!(path.parent(), HgPath::new(b"")); + +let path = HgPath::new(b"a/b"); +assert_eq!(path.parent(), HgPath::new(b"a")); + +let path = HgPath::new(b"a/other/b"); +assert_eq!(path.parent(), HgPath::new(b"a/other")); +} } diff --git a/rust/hg-core/Cargo.toml b/rust/hg-core/Cargo.toml --- a/rust/hg-core/Cargo.toml +++ b/rust/hg-core/Cargo.toml @@ -19,4 +19,5 @@ twox-hash = "1.5.0" [dev-dependencies] -tempfile = "3.1.0" \ No newline at end of file +tempfile = "3.1.0" +pretty_assertions = "0.6.1" \ No newline at end of file diff --git a/rust/Cargo.lock b/rust/Cargo.lock --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -9,6 +9,14 @@ ] [[package]] +name = "ansi_term" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index; +dependencies = [ + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] name = "arrayvec" version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index; @@ -104,6 +112,20 @@ ] [[package]] +name = "ctor" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index; +dependencies = [ + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "difference" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index; + +[[package]] name = "either" version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index; @@ -130,6 +152,7 @@ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -200,11 +223,38 @@ ] [[package]] +name = "output_vt100"