##// END OF EJS Templates
rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`...
Raphaël Gomès -
r43742:a77d4fe3 default
parent child Browse files
Show More
@@ -0,0 +1,105 b''
1 // matchers.rs
2 //
3 // Copyright 2019 Raphaël Gomès <rgomes@octobus.net>
4 //
5 // This software may be used and distributed according to the terms of the
6 // GNU General Public License version 2 or any later version.
7
8 //! Structs and types for matching files and directories.
9
10 use crate::utils::hg_path::{HgPath, HgPathBuf};
11 use std::collections::HashSet;
12
13 pub enum VisitChildrenSet {
14 /// Don't visit anything
15 Empty,
16 /// Only visit this directory
17 This,
18 /// Visit this directory and these subdirectories
19 /// TODO Should we implement a `NonEmptyHashSet`?
20 Set(HashSet<HgPathBuf>),
21 /// Visit this directory and all subdirectories
22 Recursive,
23 }
24
25 pub trait Matcher {
26 /// Explicitly listed files
27 fn file_set(&self) -> HashSet<&HgPath>;
28 /// Returns whether `filename` is in `file_set`
29 fn exact_match(&self, _filename: impl AsRef<HgPath>) -> bool {
30 false
31 }
32 /// Returns whether `filename` is matched by this matcher
33 fn matches(&self, _filename: impl AsRef<HgPath>) -> bool {
34 false
35 }
36 /// Decides whether a directory should be visited based on whether it
37 /// has potential matches in it or one of its subdirectories, and
38 /// potentially lists which subdirectories of that directory should be
39 /// visited. This is based on the match's primary, included, and excluded
40 /// patterns.
41 ///
42 /// # Example
43 ///
44 /// Assume matchers `['path:foo/bar', 'rootfilesin:qux']`, we would
45 /// return the following values (assuming the implementation of
46 /// visit_children_set is capable of recognizing this; some implementations
47 /// are not).
48 ///
49 /// ```ignore
50 /// '' -> {'foo', 'qux'}
51 /// 'baz' -> set()
52 /// 'foo' -> {'bar'}
53 /// // Ideally this would be `Recursive`, but since the prefix nature of
54 /// // matchers is applied to the entire matcher, we have to downgrade this
55 /// // to `This` due to the (yet to be implemented in Rust) non-prefix
56 /// // `RootFilesIn'-kind matcher being mixed in.
57 /// 'foo/bar' -> 'this'
58 /// 'qux' -> 'this'
59 /// ```
60 /// # Important
61 ///
62 /// Most matchers do not know if they're representing files or
63 /// directories. They see `['path:dir/f']` and don't know whether `f` is a
64 /// file or a directory, so `visit_children_set('dir')` for most matchers
65 /// will return `HashSet{ HgPath { "f" } }`, but if the matcher knows it's
66 /// a file (like the yet to be implemented in Rust `ExactMatcher` does),
67 /// it may return `VisitChildrenSet::This`.
68 /// Do not rely on the return being a `HashSet` indicating that there are
69 /// no files in this dir to investigate (or equivalently that if there are
70 /// files to investigate in 'dir' that it will always return
71 /// `VisitChildrenSet::This`).
72 fn visit_children_set(
73 &self,
74 _directory: impl AsRef<HgPath>,
75 ) -> VisitChildrenSet {
76 VisitChildrenSet::This
77 }
78 /// Matcher will match everything and `files_set()` will be empty:
79 /// optimization might be possible.
80 fn matches_everything(&self) -> bool {
81 false
82 }
83 /// Matcher will match exactly the files in `files_set()`: optimization
84 /// might be possible.
85 fn is_exact(&self) -> bool {
86 false
87 }
88 }
89
90 /// Matches everything.
91 #[derive(Debug)]
92 pub struct AlwaysMatcher;
93
94 impl Matcher for AlwaysMatcher {
95 fn file_set(&self) -> HashSet<&HgPath> {
96 HashSet::new()
97 }
98
99 fn visit_children_set(
100 &self,
101 _directory: impl AsRef<HgPath>,
102 ) -> VisitChildrenSet {
103 VisitChildrenSet::Recursive
104 }
105 }
@@ -17,6 +17,7 b' pub use dirstate::{'
17 17 StateMap, StateMapIter,
18 18 };
19 19 mod filepatterns;
20 pub mod matchers;
20 21 pub mod utils;
21 22
22 23 use crate::utils::hg_path::HgPathBuf;
General Comments 0
You need to be logged in to leave comments. Login now