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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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 }