forked from mirrors/jj
matchers: rewrite RepoPathTree::to_visit_sets() to not depend on is_dir flag
The is_dir flag will be removed soon. Since FilesMatcher doesn't set is_dir flag explicitly, is_dir is equivalent to !entries.is_empty(). OTOH, PrefixMatcher always sets is_dir, so all tree nodes are directories.
This commit is contained in:
parent
e0d5217450
commit
10f5540b3b
1 changed files with 30 additions and 16 deletions
|
@ -143,10 +143,25 @@ impl Matcher for FilesMatcher {
|
||||||
fn visit(&self, dir: &RepoPath) -> Visit {
|
fn visit(&self, dir: &RepoPath) -> Visit {
|
||||||
self.tree
|
self.tree
|
||||||
.get(dir)
|
.get(dir)
|
||||||
.map_or(Visit::Nothing, RepoPathTree::to_visit_sets)
|
.map_or(Visit::Nothing, files_tree_to_visit_sets)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn files_tree_to_visit_sets(tree: &RepoPathTree) -> Visit {
|
||||||
|
let mut dirs = HashSet::new();
|
||||||
|
let mut files = HashSet::new();
|
||||||
|
for (name, sub) in &tree.entries {
|
||||||
|
// should visit only intermediate directories
|
||||||
|
if !sub.entries.is_empty() {
|
||||||
|
dirs.insert(name.clone());
|
||||||
|
}
|
||||||
|
if sub.is_file {
|
||||||
|
files.insert(name.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Visit::sets(dirs, files)
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct PrefixMatcher {
|
pub struct PrefixMatcher {
|
||||||
tree: RepoPathTree,
|
tree: RepoPathTree,
|
||||||
|
@ -178,13 +193,26 @@ impl Matcher for PrefixMatcher {
|
||||||
}
|
}
|
||||||
// 'dir' found, and is an ancestor of prefix paths
|
// 'dir' found, and is an ancestor of prefix paths
|
||||||
if tail_path.is_root() {
|
if tail_path.is_root() {
|
||||||
return sub.to_visit_sets();
|
return prefix_tree_to_visit_sets(sub);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Visit::Nothing
|
Visit::Nothing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn prefix_tree_to_visit_sets(tree: &RepoPathTree) -> Visit {
|
||||||
|
let mut dirs = HashSet::new();
|
||||||
|
let mut files = HashSet::new();
|
||||||
|
for (name, sub) in &tree.entries {
|
||||||
|
// should visit both intermediate and prefix directories
|
||||||
|
dirs.insert(name.clone());
|
||||||
|
if sub.is_file {
|
||||||
|
files.insert(name.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Visit::sets(dirs, files)
|
||||||
|
}
|
||||||
|
|
||||||
/// Matches paths that are matched by any of the input matchers.
|
/// Matches paths that are matched by any of the input matchers.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct UnionMatcher<M1, M2> {
|
pub struct UnionMatcher<M1, M2> {
|
||||||
|
@ -380,20 +408,6 @@ impl RepoPathTree {
|
||||||
Some((sub.entries.get(name)?, components.as_path()))
|
Some((sub.entries.get(name)?, components.as_path()))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_visit_sets(&self) -> Visit {
|
|
||||||
let mut dirs = HashSet::new();
|
|
||||||
let mut files = HashSet::new();
|
|
||||||
for (name, sub) in &self.entries {
|
|
||||||
if sub.is_dir {
|
|
||||||
dirs.insert(name.clone());
|
|
||||||
}
|
|
||||||
if sub.is_file {
|
|
||||||
files.insert(name.clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Visit::sets(dirs, files)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for RepoPathTree {
|
impl Debug for RepoPathTree {
|
||||||
|
|
Loading…
Reference in a new issue