1- use regex_automata:: MatchKind ;
2-
3- use super :: Error ;
4- use crate :: { ParserSettings , RegexFormat } ;
5- use std:: ops:: Deref ;
1+ use super :: { Error , Regex } ;
2+ use crate :: RegexProvider ;
63use std:: sync:: Arc ;
74
8- /// Wrapper around [`regex_automata::meta::Regex`]
9- #[ derive( Clone ) ]
10- pub struct Regex {
11- pattern : Arc < str > ,
12- regex : regex_automata:: meta:: Regex ,
13- format : RegexFormat ,
5+ pub ( crate ) type MetaRegex = regex_automata:: meta:: Regex ;
6+
7+ impl Regex for MetaRegex {
8+ #[ inline]
9+ fn is_match ( & self , input : & [ u8 ] ) -> bool {
10+ MetaRegex :: is_match ( self , input)
11+ }
12+ }
13+
14+ /// Regex settings.
15+ #[ derive( Clone , Debug , PartialEq , Eq ) ]
16+ pub struct RegexSettings {
17+ /// Approximate size of the cache used by the DFA of a regex.
18+ /// Default: 10MB
19+ pub dfa_size_limit : usize ,
20+ /// Approximate size limit of the compiled regular expression.
21+ /// Default: 2MB
22+ pub compiled_size_limit : usize ,
23+ }
24+
25+ impl Default for RegexSettings {
26+ #[ inline]
27+ fn default ( ) -> Self {
28+ Self {
29+ // Default value extracted from the regex crate.
30+ compiled_size_limit : 10 * ( 1 << 20 ) ,
31+ // Default value extracted from the regex crate.
32+ dfa_size_limit : 2 * ( 1 << 20 ) ,
33+ }
34+ }
1435}
1536
16- impl Regex {
37+ /// Default regex provider.
38+ #[ derive( Debug , Default ) ]
39+ pub struct RegexDefaultProvider {
40+ settings : RegexSettings ,
41+ }
42+
43+ impl RegexDefaultProvider {
44+ /// Creates a new default regex provider.
45+ pub const fn new ( settings : RegexSettings ) -> Self {
46+ Self { settings }
47+ }
48+
1749 /// Retrieves the syntax configuration that will be used to build the regex.
1850 #[ inline]
19- fn syntax_config ( ) -> regex_automata:: util:: syntax:: Config {
51+ pub fn syntax_config ( ) -> regex_automata:: util:: syntax:: Config {
2052 regex_automata:: util:: syntax:: Config :: new ( )
2153 . unicode ( false )
2254 . utf8 ( false )
2355 }
2456
2557 /// Retrieves the meta configuration that will be used to build the regex.
2658 #[ inline]
27- fn meta_config ( settings : & ParserSettings ) -> regex_automata:: meta:: Config {
59+ pub fn meta_config ( settings : & RegexSettings ) -> regex_automata:: meta:: Config {
2860 regex_automata:: meta:: Config :: new ( )
29- . match_kind ( MatchKind :: LeftmostFirst )
61+ . match_kind ( regex_automata :: MatchKind :: LeftmostFirst )
3062 . utf8_empty ( false )
3163 . dfa ( false )
32- . nfa_size_limit ( Some ( settings. regex_compiled_size_limit ) )
33- . onepass_size_limit ( Some ( settings. regex_compiled_size_limit ) )
34- . dfa_size_limit ( Some ( settings. regex_compiled_size_limit ) )
35- . hybrid_cache_capacity ( settings. regex_dfa_size_limit )
64+ . nfa_size_limit ( Some ( settings. compiled_size_limit ) )
65+ . onepass_size_limit ( Some ( settings. compiled_size_limit ) )
66+ . dfa_size_limit ( Some ( settings. compiled_size_limit ) )
67+ . hybrid_cache_capacity ( settings. dfa_size_limit )
3668 }
3769
38- /// Compiles a regular expression.
39- pub fn new (
40- pattern : & str ,
41- format : RegexFormat ,
42- settings : & ParserSettings ,
43- ) -> Result < Self , Error > {
70+ /// Builds a new regex object from the provided pattern.
71+ pub fn build ( & self , pattern : & str ) -> Result < MetaRegex , Error > {
4472 :: regex_automata:: meta:: Builder :: new ( )
45- . configure ( Self :: meta_config ( settings) )
73+ . configure ( Self :: meta_config ( & self . settings ) )
4674 . syntax ( Self :: syntax_config ( ) )
4775 . build ( pattern)
48- . map ( |regex| Regex {
49- pattern : Arc :: from ( pattern) ,
50- regex,
51- format,
52- } )
5376 . map_err ( |err| {
5477 if let Some ( limit) = err. size_limit ( ) {
5578 Error :: CompiledTooBig ( limit)
@@ -60,45 +83,27 @@ impl Regex {
6083 }
6184 } )
6285 }
63-
64- /// Returns the pattern of this regex.
65- #[ inline]
66- pub fn as_str ( & self ) -> & str {
67- & self . pattern
68- }
69-
70- /// Returns the format used by the pattern.
71- #[ inline]
72- pub fn format ( & self ) -> RegexFormat {
73- self . format
74- }
7586}
7687
77- impl From < Regex > for regex_automata:: meta:: Regex {
78- #[ inline]
79- fn from ( regex : Regex ) -> Self {
80- regex. regex
81- }
82- }
83-
84- impl Deref for Regex {
85- type Target = regex_automata:: meta:: Regex ;
86-
87- #[ inline]
88- fn deref ( & self ) -> & Self :: Target {
89- & self . regex
88+ impl RegexProvider for RegexDefaultProvider {
89+ fn lookup_regex ( & self , pattern : & str ) -> Result < Arc < dyn Regex > , Error > {
90+ self . build ( pattern) . map ( |re| Arc :: new ( re) as Arc < dyn Regex > )
9091 }
9192}
9293
9394#[ test]
9495fn test_compiled_size_limit ( ) {
96+ use super :: { RegexDefaultProvider , RegexSettings } ;
97+ use crate :: { RegexExpr , RegexFormat } ;
98+
9599 const COMPILED_SIZE_LIMIT : usize = 1024 * 1024 ;
96- let settings = ParserSettings {
97- regex_compiled_size_limit : COMPILED_SIZE_LIMIT ,
100+ let settings = RegexSettings {
101+ compiled_size_limit : COMPILED_SIZE_LIMIT ,
98102 ..Default :: default ( )
99103 } ;
104+ let regex_provider = RegexDefaultProvider :: new ( settings) ;
100105 assert_eq ! (
101- Regex :: new( ".{4079,65535}" , RegexFormat :: Literal , & settings ) ,
106+ RegexExpr :: new( ".{4079,65535}" , RegexFormat :: Literal , & regex_provider ) ,
102107 Err ( Error :: CompiledTooBig ( COMPILED_SIZE_LIMIT ) )
103108 ) ;
104109}
0 commit comments