Mercurial > hg
annotate rust/hg-core/src/dirstate_tree/path_with_basename.rs @ 51568:2a89d2f6336f stable
match: rename RootFiles to RootFilesIn for more consistency
author | Arseniy Alekseyev <aalekseyev@janestreet.com> |
---|---|
date | Fri, 12 Apr 2024 14:21:14 +0100 |
parents | 2a9ddc8094c7 |
children |
rev | line source |
---|---|
47096
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
1 use crate::utils::hg_path::HgPath; |
47126
ecfe0819ada5
dirstate-tree: Borrow paths from the "on disk" bytes
Simon Sapin <simon.sapin@octobus.net>
parents:
47119
diff
changeset
|
2 use std::borrow::{Borrow, Cow}; |
47096
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
3 |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
4 /// Wraps `HgPath` or `HgPathBuf` to make it behave "as" its last path |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
5 /// component, a.k.a. its base name (as in Python’s `os.path.basename`), but |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
6 /// also allow recovering the full path. |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
7 /// |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
8 /// "Behaving as" means that equality and comparison consider only the base |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
9 /// name, and `std::borrow::Borrow` is implemented to return only the base |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
10 /// name. This allows using the base name as a map key while still being able |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
11 /// to recover the full path, in a single memory allocation. |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
12 #[derive(Debug)] |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
13 pub struct WithBasename<T> { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
14 full_path: T, |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
15 |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
16 /// The position after the last slash separator in `full_path`, or `0` |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
17 /// if there is no slash. |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
18 base_name_start: usize, |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
19 } |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
20 |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
21 impl<T> WithBasename<T> { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
22 pub fn full_path(&self) -> &T { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
23 &self.full_path |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
24 } |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
25 } |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
26 |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
27 fn find_base_name_start(full_path: &HgPath) -> usize { |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
28 if let Some(last_slash_position) = |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
29 full_path.as_bytes().iter().rposition(|&byte| byte == b'/') |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
30 { |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
31 last_slash_position + 1 |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
32 } else { |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
33 0 |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
34 } |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
35 } |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
36 |
47096
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
37 impl<T: AsRef<HgPath>> WithBasename<T> { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
38 pub fn new(full_path: T) -> Self { |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
39 Self { |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
40 base_name_start: find_base_name_start(full_path.as_ref()), |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
41 full_path, |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
42 } |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
43 } |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
44 |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
45 pub fn from_raw_parts(full_path: T, base_name_start: usize) -> Self { |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
46 debug_assert_eq!( |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
47 base_name_start, |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
48 find_base_name_start(full_path.as_ref()) |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
49 ); |
47096
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
50 Self { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
51 base_name_start, |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
52 full_path, |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
53 } |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
54 } |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
55 |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
56 pub fn base_name(&self) -> &HgPath { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
57 HgPath::new( |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
58 &self.full_path.as_ref().as_bytes()[self.base_name_start..], |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
59 ) |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
60 } |
47283
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
61 |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
62 pub fn base_name_start(&self) -> usize { |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
63 self.base_name_start |
2a9ddc8094c7
dirstate-v2: Change the on-disk format to be tree-shaped
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
64 } |
47096
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
65 } |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
66 |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
67 impl<T: AsRef<HgPath>> Borrow<HgPath> for WithBasename<T> { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
68 fn borrow(&self) -> &HgPath { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
69 self.base_name() |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
70 } |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
71 } |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
72 |
47119
15395fd8ab28
dirstate-tree: Use HashMap instead of BTreeMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47096
diff
changeset
|
73 impl<T: AsRef<HgPath>> std::hash::Hash for WithBasename<T> { |
15395fd8ab28
dirstate-tree: Use HashMap instead of BTreeMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47096
diff
changeset
|
74 fn hash<H: std::hash::Hasher>(&self, hasher: &mut H) { |
15395fd8ab28
dirstate-tree: Use HashMap instead of BTreeMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47096
diff
changeset
|
75 self.base_name().hash(hasher) |
15395fd8ab28
dirstate-tree: Use HashMap instead of BTreeMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47096
diff
changeset
|
76 } |
15395fd8ab28
dirstate-tree: Use HashMap instead of BTreeMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47096
diff
changeset
|
77 } |
15395fd8ab28
dirstate-tree: Use HashMap instead of BTreeMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47096
diff
changeset
|
78 |
47096
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
79 impl<T: AsRef<HgPath> + PartialEq> PartialEq for WithBasename<T> { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
80 fn eq(&self, other: &Self) -> bool { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
81 self.base_name() == other.base_name() |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
82 } |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
83 } |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
84 |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
85 impl<T: AsRef<HgPath> + Eq> Eq for WithBasename<T> {} |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
86 |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
87 impl<T: AsRef<HgPath> + PartialOrd> PartialOrd for WithBasename<T> { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
88 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
89 self.base_name().partial_cmp(other.base_name()) |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
90 } |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
91 } |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
92 |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
93 impl<T: AsRef<HgPath> + Ord> Ord for WithBasename<T> { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
94 fn cmp(&self, other: &Self) -> std::cmp::Ordering { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
95 self.base_name().cmp(other.base_name()) |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
96 } |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
97 } |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
98 |
47126
ecfe0819ada5
dirstate-tree: Borrow paths from the "on disk" bytes
Simon Sapin <simon.sapin@octobus.net>
parents:
47119
diff
changeset
|
99 impl<'a> WithBasename<&'a HgPath> { |
ecfe0819ada5
dirstate-tree: Borrow paths from the "on disk" bytes
Simon Sapin <simon.sapin@octobus.net>
parents:
47119
diff
changeset
|
100 pub fn to_cow_borrowed(self) -> WithBasename<Cow<'a, HgPath>> { |
47096
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
101 WithBasename { |
47126
ecfe0819ada5
dirstate-tree: Borrow paths from the "on disk" bytes
Simon Sapin <simon.sapin@octobus.net>
parents:
47119
diff
changeset
|
102 full_path: Cow::Borrowed(self.full_path), |
ecfe0819ada5
dirstate-tree: Borrow paths from the "on disk" bytes
Simon Sapin <simon.sapin@octobus.net>
parents:
47119
diff
changeset
|
103 base_name_start: self.base_name_start, |
ecfe0819ada5
dirstate-tree: Borrow paths from the "on disk" bytes
Simon Sapin <simon.sapin@octobus.net>
parents:
47119
diff
changeset
|
104 } |
ecfe0819ada5
dirstate-tree: Borrow paths from the "on disk" bytes
Simon Sapin <simon.sapin@octobus.net>
parents:
47119
diff
changeset
|
105 } |
ecfe0819ada5
dirstate-tree: Borrow paths from the "on disk" bytes
Simon Sapin <simon.sapin@octobus.net>
parents:
47119
diff
changeset
|
106 |
ecfe0819ada5
dirstate-tree: Borrow paths from the "on disk" bytes
Simon Sapin <simon.sapin@octobus.net>
parents:
47119
diff
changeset
|
107 pub fn to_cow_owned<'b>(self) -> WithBasename<Cow<'b, HgPath>> { |
ecfe0819ada5
dirstate-tree: Borrow paths from the "on disk" bytes
Simon Sapin <simon.sapin@octobus.net>
parents:
47119
diff
changeset
|
108 WithBasename { |
ecfe0819ada5
dirstate-tree: Borrow paths from the "on disk" bytes
Simon Sapin <simon.sapin@octobus.net>
parents:
47119
diff
changeset
|
109 full_path: Cow::Owned(self.full_path.to_owned()), |
47096
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
110 base_name_start: self.base_name_start, |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
111 } |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
112 } |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
113 } |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
114 |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
115 impl<'a> WithBasename<&'a HgPath> { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
116 /// Returns an iterator of `WithBasename<&HgPath>` for the ancestor |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
117 /// directory paths of the given `path`, as well as `path` itself. |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
118 /// |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
119 /// For example, the full paths of inclusive ancestors of "a/b/c" are "a", |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
120 /// "a/b", and "a/b/c" in that order. |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
121 pub fn inclusive_ancestors_of( |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
122 path: &'a HgPath, |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
123 ) -> impl Iterator<Item = WithBasename<&'a HgPath>> { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
124 let mut slash_positions = |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
125 path.as_bytes().iter().enumerate().filter_map(|(i, &byte)| { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
126 if byte == b'/' { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
127 Some(i) |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
128 } else { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
129 None |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
130 } |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
131 }); |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
132 let mut opt_next_component_start = Some(0); |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
133 std::iter::from_fn(move || { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
134 opt_next_component_start.take().map(|next_component_start| { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
135 if let Some(slash_pos) = slash_positions.next() { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
136 opt_next_component_start = Some(slash_pos + 1); |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
137 Self { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
138 full_path: HgPath::new(&path.as_bytes()[..slash_pos]), |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
139 base_name_start: next_component_start, |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
140 } |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
141 } else { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
142 // Not setting `opt_next_component_start` here: there will |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
143 // be no iteration after this one because `.take()` set it |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
144 // to `None`. |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
145 Self { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
146 full_path: path, |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
147 base_name_start: next_component_start, |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
148 } |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
149 } |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
150 }) |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
151 }) |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
152 } |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
153 } |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
154 |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
155 #[test] |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
156 fn test() { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
157 let a = WithBasename::new(HgPath::new("a").to_owned()); |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
158 assert_eq!(&**a.full_path(), HgPath::new(b"a")); |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
159 assert_eq!(a.base_name(), HgPath::new(b"a")); |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
160 |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
161 let cba = WithBasename::new(HgPath::new("c/b/a").to_owned()); |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
162 assert_eq!(&**cba.full_path(), HgPath::new(b"c/b/a")); |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
163 assert_eq!(cba.base_name(), HgPath::new(b"a")); |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
164 |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
165 assert_eq!(a, cba); |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
166 let borrowed: &HgPath = cba.borrow(); |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
167 assert_eq!(borrowed, HgPath::new("a")); |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
168 } |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
169 |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
170 #[test] |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
171 fn test_inclusive_ancestors() { |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
172 let mut iter = WithBasename::inclusive_ancestors_of(HgPath::new("a/bb/c")); |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
173 |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
174 let next = iter.next().unwrap(); |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
175 assert_eq!(*next.full_path(), HgPath::new("a")); |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
176 assert_eq!(next.base_name(), HgPath::new("a")); |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
177 |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
178 let next = iter.next().unwrap(); |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
179 assert_eq!(*next.full_path(), HgPath::new("a/bb")); |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
180 assert_eq!(next.base_name(), HgPath::new("bb")); |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
181 |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
182 let next = iter.next().unwrap(); |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
183 assert_eq!(*next.full_path(), HgPath::new("a/bb/c")); |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
184 assert_eq!(next.base_name(), HgPath::new("c")); |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
185 |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
186 assert!(iter.next().is_none()); |
3c11c24b82b6
dirstate-tree: Add `WithBasename` wrapper for `HgPath`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
187 } |