Mercurial > public > mercurial-scm > hg-stable
annotate rust/hg-core/src/utils/files.rs @ 42586:cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
This is modeled after std::path::Path::ancestors().
find_dirs(b"") yields b"" because Mercurial's util.finddirs() works in that
way, and the test case for DirsMultiset expects such behavior.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Sun, 30 Jun 2019 18:32:43 +0900 |
parents | f305f1d7d559 |
children | 4b3b27d567d5 |
rev | line source |
---|---|
42586
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
1 use std::iter::FusedIterator; |
42453
9609430d3625
rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
2 use std::path::Path; |
9609430d3625
rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
3 |
9609430d3625
rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
4 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
|
5 let os_str; |
9609430d3625
rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
6 #[cfg(unix)] |
9609430d3625
rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
7 { |
9609430d3625
rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
8 use std::os::unix::ffi::OsStrExt; |
9609430d3625
rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
9 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
|
10 } |
9609430d3625
rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
11 #[cfg(windows)] |
9609430d3625
rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
12 { |
42499
f305f1d7d559
rust-filepatterns: add comment about Windows path handling
Yuya Nishihara <yuya@tcha.org>
parents:
42453
diff
changeset
|
13 // 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
|
14 // 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
|
15 use std::os::windows::ffi::OsStrExt; |
9609430d3625
rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
16 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
|
17 } |
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 Path::new(os_str) |
9609430d3625
rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
20 } |
42586
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
21 |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
22 /// 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
|
23 #[derive(Copy, Clone, Debug)] |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
24 pub struct Ancestors<'a> { |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
25 next: Option<&'a [u8]>, |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
26 } |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
27 |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
28 impl<'a> Iterator for Ancestors<'a> { |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
29 // 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
|
30 type Item = &'a [u8]; |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
31 |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
32 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
|
33 let next = self.next; |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
34 self.next = match self.next { |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
35 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
|
36 Some(s) => { |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
37 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
|
38 Some(&s[..p]) |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
39 } |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
40 None => None, |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
41 }; |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
42 next |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
43 } |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
44 } |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
45 |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
46 impl<'a> FusedIterator for Ancestors<'a> {} |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
47 |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
48 /// 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
|
49 /// path. |
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 /// 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
|
52 /// |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
53 /// 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
|
54 /// directory.) |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
55 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
|
56 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
|
57 if !path.is_empty() { |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
58 dirs.next(); // skip itself |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
59 } |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
60 dirs |
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 |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
63 #[cfg(test)] |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
64 mod tests { |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
65 #[test] |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
66 fn find_dirs_some() { |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
67 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
|
68 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
|
69 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
|
70 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
|
71 assert_eq!(dirs.next(), None); |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
72 assert_eq!(dirs.next(), None); |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
73 } |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
74 |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
75 #[test] |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
76 fn find_dirs_empty() { |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
77 // 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
|
78 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
|
79 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
|
80 assert_eq!(dirs.next(), None); |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
81 assert_eq!(dirs.next(), None); |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
82 } |
cad3dde7a573
rust-dirstate: add helper to iterate ancestor paths
Yuya Nishihara <yuya@tcha.org>
parents:
42499
diff
changeset
|
83 } |