diff rust/hg-core/src/utils/files.rs @ 42957:7a01778bc7b7

rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf Differential Revision: https://phab.mercurial-scm.org/D6774
author Raphaël Gomès <rgomes@octobus.net>
date Sun, 01 Sep 2019 20:53:14 +0200
parents b1b984f9c01d
children 98d996a138de
line wrap: on
line diff
--- a/rust/hg-core/src/utils/files.rs	Sun Sep 01 20:53:14 2019 +0200
+++ b/rust/hg-core/src/utils/files.rs	Sun Sep 01 20:53:14 2019 +0200
@@ -9,7 +9,9 @@
 
 //! Functions for fiddling with files.
 
+use crate::utils::hg_path::{HgPath, HgPathBuf};
 use std::iter::FusedIterator;
+
 use std::path::Path;
 
 pub fn get_path_from_bytes(bytes: &[u8]) -> &Path {
@@ -23,8 +25,7 @@
     {
         // TODO: convert from Windows MBCS (ANSI encoding) to WTF8.
         // Perhaps, the return type would have to be Result<PathBuf>.
-        use std::os::windows::ffi::OsStrExt;
-        os_str = std::ffi::OsString::from_wide(bytes);
+        unimplemented!()
     }
 
     Path::new(os_str)
@@ -33,20 +34,19 @@
 /// An iterator over repository path yielding itself and its ancestors.
 #[derive(Copy, Clone, Debug)]
 pub struct Ancestors<'a> {
-    next: Option<&'a [u8]>,
+    next: Option<&'a HgPath>,
 }
 
 impl<'a> Iterator for Ancestors<'a> {
-    // if we had an HgPath type, this would yield &'a HgPath
-    type Item = &'a [u8];
+    type Item = &'a HgPath;
 
     fn next(&mut self) -> Option<Self::Item> {
         let next = self.next;
         self.next = match self.next {
             Some(s) if s.is_empty() => None,
             Some(s) => {
-                let p = s.iter().rposition(|&c| c == b'/').unwrap_or(0);
-                Some(&s[..p])
+                let p = s.bytes().rposition(|c| *c == b'/').unwrap_or(0);
+                Some(HgPath::new(&s.as_bytes()[..p]))
             }
             None => None,
         };
@@ -63,7 +63,7 @@
 ///
 /// The path itself isn't included unless it is b"" (meaning the root
 /// directory.)
-pub fn find_dirs<'a>(path: &'a [u8]) -> Ancestors<'a> {
+pub fn find_dirs<'a>(path: &'a HgPath) -> Ancestors<'a> {
     let mut dirs = Ancestors { next: Some(path) };
     if !path.is_empty() {
         dirs.next(); // skip itself
@@ -71,23 +71,24 @@
     dirs
 }
 
-/// TODO improve handling of utf8 file names. Our overall strategy for
-/// filenames has to be revisited anyway, since Windows is UTF-16.
-pub fn normalize_case(bytes: &[u8]) -> Vec<u8> {
+/// TODO more than ASCII?
+pub fn normalize_case(path: &HgPath) -> HgPathBuf {
     #[cfg(windows)] // NTFS compares via upper()
-    return bytes.to_ascii_uppercase();
+    return path.to_ascii_uppercase();
     #[cfg(unix)]
-    bytes.to_ascii_lowercase()
+    path.to_ascii_lowercase()
 }
 
 #[cfg(test)]
 mod tests {
+    use super::*;
+
     #[test]
     fn find_dirs_some() {
-        let mut dirs = super::find_dirs(b"foo/bar/baz");
-        assert_eq!(dirs.next(), Some(b"foo/bar".as_ref()));
-        assert_eq!(dirs.next(), Some(b"foo".as_ref()));
-        assert_eq!(dirs.next(), Some(b"".as_ref()));
+        let mut dirs = super::find_dirs(HgPath::new(b"foo/bar/baz"));
+        assert_eq!(dirs.next(), Some(HgPath::new(b"foo/bar")));
+        assert_eq!(dirs.next(), Some(HgPath::new(b"foo")));
+        assert_eq!(dirs.next(), Some(HgPath::new(b"")));
         assert_eq!(dirs.next(), None);
         assert_eq!(dirs.next(), None);
     }
@@ -95,8 +96,8 @@
     #[test]
     fn find_dirs_empty() {
         // looks weird, but mercurial.util.finddirs(b"") yields b""
-        let mut dirs = super::find_dirs(b"");
-        assert_eq!(dirs.next(), Some(b"".as_ref()));
+        let mut dirs = super::find_dirs(HgPath::new(b""));
+        assert_eq!(dirs.next(), Some(HgPath::new(b"")));
         assert_eq!(dirs.next(), None);
         assert_eq!(dirs.next(), None);
     }