D7867: rust-hg-path: add useful methods to `HgPath`

2020-02-06 Thread Raphaël Gomès
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`

2020-02-06 Thread martinvonz (Martin von Zweigbergk)
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`

2020-02-06 Thread Raphaël Gomès
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`

2020-02-06 Thread Raphaël Gomès
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`

2020-01-24 Thread martinvonz (Martin von Zweigbergk)
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`

2020-01-24 Thread Raphaël Gomès
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`

2020-01-24 Thread martinvonz (Martin von Zweigbergk)
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`

2020-01-24 Thread Raphaël Gomès
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`

2020-01-23 Thread martinvonz (Martin von Zweigbergk)
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`

2020-01-16 Thread Raphaël Gomès
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`

2020-01-16 Thread Raphaël Gomès
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`

2020-01-16 Thread kevincox (Kevin Cox)
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`

2020-01-16 Thread Raphaël Gomès
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`

2020-01-15 Thread Raphaël Gomès
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`

2020-01-15 Thread kevincox (Kevin Cox)
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`

2020-01-14 Thread Raphaël Gomès
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"