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