1
- use pyo3:: exceptions:: PyRuntimeError ;
2
- use pyo3:: prelude:: * ;
3
- use regex:: Regex ;
1
+ use std:: path:: Path ;
4
2
use std:: collections:: { HashMap , HashSet } ;
3
+ use regex:: Regex ;
4
+ use pyo3:: prelude:: * ;
5
+ use pyo3:: exceptions:: PyRuntimeError ;
6
+ use aho_corasick:: AhoCorasick ;
5
7
6
8
struct ContentRule {
7
9
name : String ,
@@ -16,19 +18,31 @@ struct FilePathRule {
16
18
}
17
19
18
20
#[ pyclass]
19
- #[ derive( Default ) ]
20
21
pub struct RulesManager {
21
22
file_extensions_to_skip : HashSet < String > ,
22
- file_paths_to_skip : HashSet < String > ,
23
+ file_paths_to_skip : Vec < String > ,
24
+ file_paths_to_skip_ac : Option < AhoCorasick > ,
23
25
content_rules : Vec < ContentRule > ,
24
26
file_path_rules : Vec < FilePathRule > ,
25
27
}
26
28
29
+ impl Default for RulesManager {
30
+ fn default ( ) -> Self {
31
+ Self :: new ( )
32
+ }
33
+ }
34
+
27
35
#[ pymethods]
28
36
impl RulesManager {
29
37
#[ new]
30
38
pub fn new ( ) -> Self {
31
- RulesManager :: default ( )
39
+ RulesManager {
40
+ file_extensions_to_skip : HashSet :: default ( ) ,
41
+ file_paths_to_skip : Vec :: default ( ) ,
42
+ file_paths_to_skip_ac : None ,
43
+ content_rules : Vec :: default ( ) ,
44
+ file_path_rules : Vec :: default ( ) ,
45
+ }
32
46
}
33
47
34
48
pub fn add_content_rule (
@@ -168,7 +182,12 @@ impl RulesManager {
168
182
PyRuntimeError :: new_err ( "File path can not be empty" )
169
183
)
170
184
}
171
- self . file_paths_to_skip . insert ( file_path. to_ascii_lowercase ( ) ) ;
185
+ self . file_paths_to_skip . push ( file_path. to_ascii_lowercase ( ) ) ;
186
+ self . file_paths_to_skip_ac = Some (
187
+ AhoCorasick :: new_auto_configured (
188
+ self . file_paths_to_skip . as_slice ( )
189
+ )
190
+ ) ;
172
191
173
192
Ok ( ( ) )
174
193
}
@@ -177,20 +196,16 @@ impl RulesManager {
177
196
& self ,
178
197
file_path : & str ,
179
198
) -> bool {
180
- if self . file_extensions_to_skip . iter ( ) . any (
181
- |file_extension_to_skip| {
182
- file_path . ends_with ( file_extension_to_skip )
199
+ if let Some ( file_extension ) = Path :: new ( file_path ) . extension ( ) {
200
+ if self . file_extensions_to_skip . contains ( file_extension . to_string_lossy ( ) . as_ref ( ) ) {
201
+ return false ;
183
202
}
184
- ) {
185
- return false ;
186
203
}
187
204
188
- if self . file_paths_to_skip . iter ( ) . any (
189
- |file_path_to_skip| {
190
- file_path . contains ( file_path_to_skip )
205
+ if let Some ( file_paths_to_skip_patterns ) = & self . file_paths_to_skip_ac {
206
+ if file_paths_to_skip_patterns . is_match ( file_path ) {
207
+ return false ;
191
208
}
192
- ) {
193
- return false ;
194
209
}
195
210
196
211
true
0 commit comments