Mercurial > public > mercurial-scm > hg-stable
annotate rust/hg-core/src/utils/files.rs @ 42850:b1b984f9c01d
rust-utils: add normalize_case util to mirror Python one
While we still don't handle filenames properly cross-platform, this at least
sticks closer to the Python behavior.
Differential Revision: https://phab.mercurial-scm.org/D6756
author | Rapha?l Gom?s <rgomes@octobus.net> |
---|---|
date | Thu, 22 Aug 2019 14:31:07 +0200 |
parents | 4b3b27d567d5 |
children | 7a01778bc7b7 |
rev | line source |
---|---|
42767
4b3b27d567d5
rust-docstrings: add missing module docstrings
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42586
diff
changeset
|
1 // files.rs |
4b3b27d567d5
rust-docstrings: add missing module docstrings
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42586
diff
changeset
|
2 // |
4b3b27d567d5
rust-docstrings: add missing module docstrings
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42586
diff
changeset
|
3 // Copyright 2019 |
4b3b27d567d5
rust-docstrings: add missing module docstrings
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42586
diff
changeset
|
4 // Raphaël Gomès <rgomes@octobus.net>, |
4b3b27d567d5
rust-docstrings: add missing module docstrings
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42586
diff
changeset
|
5 // Yuya Nishihara <yuya@tcha.org> |
4b3b27d567d5
rust-docstrings: add missing module docstrings
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42586
diff
changeset
|
6 // |
4b3b27d567d5
rust-docstrings: add missing module docstrings
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42586
diff
changeset
|
7 // This software may be used and distributed according to the terms of the |
4b3b27d567d5
rust-docstrings: add missing module docstrings
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42586
diff
changeset
|
8 // GNU General Public License version 2 or any later version. |
4b3b27d567d5
rust-docstrings: add missing module docstrings
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42586
diff
changeset
|
9 |
4b3b27d567d5
rust-docstrings: add missing module docstrings
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42586
diff
changeset
|
10 //! Functions for fiddling with files. |
4b3b27d567d5
rust-docstrings: add missing module docstrings
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42586
diff
changeset
|
11 |
42586
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
12 use std::iter::FusedIterator; |
42453
9609430d3625
rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
13 use std::path::Path; |
9609430d3625
rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
14 |
9609430d3625
rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
15 pub fn get_path_from_bytes(bytes: &[u8]) -> &Path { |
9609430d3625
rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
16 let os_str; |
9609430d3625
rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
17 #[cfg(unix)] |
9609430d3625
rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
18 { |
9609430d3625
rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
19 use std::os::unix::ffi::OsStrExt; |
9609430d3625
rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
20 os_str = std::ffi::OsStr::from_bytes(bytes); |
9609430d3625
rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
21 } |
9609430d3625
rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
22 #[cfg(windows)] |
9609430d3625
rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
23 { |
42499
f305f1d7d559
rust-filepatterns: add comment about Windows path handling
Yuya Nishihara <yuya@tcha.org>
parents:
42453
diff
changeset
|
24 // TODO: convert from Windows MBCS (ANSI encoding) to WTF8. |
f305f1d7d559
rust-filepatterns: add comment about Windows path handling
Yuya Nishihara <yuya@tcha.org>
parents:
42453
diff
changeset
|
25 // Perhaps, the return type would have to be Result<PathBuf>. |
42453
9609430d3625
rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
26 use std::os::windows::ffi::OsStrExt; |
9609430d3625
rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
27 os_str = std::ffi::OsString::from_wide(bytes); |
9609430d3625
rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
28 } |
9609430d3625
rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
29 |
9609430d3625
rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
30 Path::new(os_str) |
9609430d3625
rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
31 } |
42586
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
32 |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
33 /// An iterator over repository path yielding itself and its ancestors. |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
34 #[derive(Copy, Clone, Debug)] |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
35 pub struct Ancestors<'a> { |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
36 next: Option<&'a [u8]>, |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
37 } |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
38 |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
39 impl<'a> Iterator for Ancestors<'a> { |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
40 // if we had an HgPath type, this would yield &'a HgPath |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
41 type Item = &'a [u8]; |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
42 |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
43 fn next(&mut self) -> Option<Self::Item> { |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
44 let next = self.next; |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
45 self.next = match self.next { |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
46 Some(s) if s.is_empty() => None, |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
47 Some(s) => { |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
48 let p = s.iter().rposition(|&c| c == b'/').unwrap_or(0); |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
49 Some(&s[..p]) |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
50 } |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
51 None => None, |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
52 }; |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
53 next |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
54 } |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
55 } |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
56 |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
57 impl<'a> FusedIterator for Ancestors<'a> {} |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
58 |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
59 /// Returns an iterator yielding ancestor directories of the given repository |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
60 /// path. |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
61 /// |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
62 /// The path is separated by '/', and must not start with '/'. |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
63 /// |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
64 /// The path itself isn't included unless it is b"" (meaning the root |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
65 /// directory.) |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
66 pub fn find_dirs<'a>(path: &'a [u8]) -> Ancestors<'a> { |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
67 let mut dirs = Ancestors { next: Some(path) }; |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
68 if !path.is_empty() { |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
69 dirs.next(); // skip itself |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
70 } |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
71 dirs |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
72 } |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
73 |
42850
b1b984f9c01d
rust-utils: add normalize_case util to mirror Python one
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42767
diff
changeset
|
74 /// TODO improve handling of utf8 file names. Our overall strategy for |
b1b984f9c01d
rust-utils: add normalize_case util to mirror Python one
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42767
diff
changeset
|
75 /// filenames has to be revisited anyway, since Windows is UTF-16. |
b1b984f9c01d
rust-utils: add normalize_case util to mirror Python one
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42767
diff
changeset
|
76 pub fn normalize_case(bytes: &[u8]) -> Vec<u8> { |
b1b984f9c01d
rust-utils: add normalize_case util to mirror Python one
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42767
diff
changeset
|
77 #[cfg(windows)] // NTFS compares via upper() |
b1b984f9c01d
rust-utils: add normalize_case util to mirror Python one
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42767
diff
changeset
|
78 return bytes.to_ascii_uppercase(); |
b1b984f9c01d
rust-utils: add normalize_case util to mirror Python one
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42767
diff
changeset
|
79 #[cfg(unix)] |
b1b984f9c01d
rust-utils: add normalize_case util to mirror Python one
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42767
diff
changeset
|
80 bytes.to_ascii_lowercase() |
b1b984f9c01d
rust-utils: add normalize_case util to mirror Python one
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42767
diff
changeset
|
81 } |
b1b984f9c01d
rust-utils: add normalize_case util to mirror Python one
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42767
diff
changeset
|
82 |
42586
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
83 #[cfg(test)] |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
84 mod tests { |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
85 #[test] |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
86 fn find_dirs_some() { |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
87 let mut dirs = super::find_dirs(b"foo/bar/baz"); |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
88 assert_eq!(dirs.next(), Some(b"foo/bar".as_ref())); |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
89 assert_eq!(dirs.next(), Some(b"foo".as_ref())); |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
90 assert_eq!(dirs.next(), Some(b"".as_ref())); |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
91 assert_eq!(dirs.next(), None); |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
92 assert_eq!(dirs.next(), None); |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
93 } |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
94 |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
95 #[test] |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
96 fn find_dirs_empty() { |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
97 // looks weird, but mercurial.util.finddirs(b"") yields b"" |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
98 let mut dirs = super::find_dirs(b""); |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
99 assert_eq!(dirs.next(), Some(b"".as_ref())); |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
100 assert_eq!(dirs.next(), None); |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
101 assert_eq!(dirs.next(), None); |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
102 } |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
103 } |