author | Simon Sapin <simon.sapin@octobus.net> |
Thu, 14 Oct 2021 16:39:16 +0200 | |
changeset 48232 | f7fd629ffb98 |
parent 47283 | 2a9ddc8094c7 |
permissions | -rw-r--r-- |
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 |
} |