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