1 use { 2 proc_macro2, 3 quote::quote, 4 syn::LitStr, 5 }; 6 7 /// The lazy static regex building code, which is produced and 8 /// inserted by all lazy-regex macros 9 pub(crate) struct RegexCode { 10 pub regex: regex::Regex, 11 pub build: proc_macro2::TokenStream, 12 } 13 14 impl From<LitStr> for RegexCode { from(lit_str: LitStr) -> Self15 fn from(lit_str: LitStr) -> Self { 16 let regex_string = lit_str.value(); 17 let mut case_insensitive = false; 18 let mut multi_line = false; 19 let mut dot_matches_new_line = false; 20 let mut ignore_whitespace = false; 21 let mut swap_greed = false; 22 for ch in lit_str.suffix().chars() { 23 match ch { 24 'i' => case_insensitive = true, 25 'm' => multi_line = true, 26 's' => dot_matches_new_line = true, 27 'x' => ignore_whitespace = true, 28 'U' => swap_greed = true, 29 _ => { 30 panic!("unrecognized regex flag {:?}", ch); 31 } 32 }; 33 } 34 35 // the next line prevents compilation if the 36 // literal is invalid as a regular expression 37 let regex = regex::Regex::new(®ex_string).unwrap(); 38 39 let build = quote! {{ 40 lazy_regex::Lazy::new(|| { 41 //println!("compiling regex {:?}", #regex_string); 42 let mut builder = lazy_regex::RegexBuilder::new(#regex_string); 43 builder.case_insensitive(#case_insensitive); 44 builder.multi_line(#multi_line); 45 builder.dot_matches_new_line(#dot_matches_new_line); 46 builder.ignore_whitespace(#ignore_whitespace); 47 builder.swap_greed(#swap_greed); 48 builder.build().unwrap() 49 }) 50 }}; 51 52 Self { regex, build } 53 } 54 } 55 56 57