ct_regex_internal/codegen/
args.rs1use std::{collections::HashSet, fmt::{self, Display}};
2
3use syn::{Ident, LitStr, Token, Visibility, parse::{Parse, ParseStream}};
4
5use crate::codegen::ConfigExt;
6
7pub enum RegexArgType {
8 Regex(RegexArgs),
9 Anon(AnonRegexArgs),
10}
11
12impl Parse for RegexArgType {
13 fn parse(input: ParseStream) -> syn::Result<Self> {
14 if input.fork().parse::<RegexArgs>().is_ok() {
15 Ok(RegexArgType::Regex(input.parse()?))
16 } else {
17 Ok(RegexArgType::Anon(input.parse()?))
18 }
19 }
20}
21
22pub struct RegexArgs {
23 pub vis: Visibility,
24 pub name: Ident,
25 pub pat: LitStr,
26 pub flags: Flags,
27}
28
29impl Parse for RegexArgs {
30 fn parse(input: ParseStream) -> syn::Result<Self> {
31 let vis = input.parse()?;
32 let name = input.parse()?;
33 input.parse::<Token![=]>()?;
34 let pat = input.parse()?;
35 let flags = input.parse()?;
36 Ok(RegexArgs {
37 vis,
38 name,
39 pat,
40 flags,
41 })
42 }
43}
44
45pub struct AnonRegexArgs {
46 pub pat: LitStr,
47 pub flags: Flags,
48}
49
50impl Parse for AnonRegexArgs {
51 fn parse(input: ParseStream) -> syn::Result<Self> {
52 Ok(AnonRegexArgs {
53 pat: input.parse()?,
54 flags: input.parse()?,
55 })
56 }
57}
58
59pub struct Flags(pub HashSet<char>);
60
61impl Parse for Flags {
62 fn parse(input: ParseStream) -> syn::Result<Self> {
63 let sep = input.parse::<Token![/]>();
64
65 let lit: syn::Result<LitStr> = input.parse();
66
67 let set = lit
68 .and_then(|l| sep.map(|_| l))
69 .map(|l| l.value())
70 .unwrap_or_default()
71 .chars()
72 .collect();
73
74 Ok(Flags(set))
75 }
76}
77
78impl Flags {
79 pub fn create_config(self) -> ConfigExt {
80 let mut config = ConfigExt::default();
81
82 for c in self.0 {
83 match c {
84 'i' => config.case_insensitive(true),
85 'm' => config.multi_line(true),
86 's' => config.dot_matches_new_line(true),
87 'R' => config.crlf(true),
88 'U' => config.swap_greed(true),
89 'x' => config.ignore_whitespace(true),
90 'c' => config.complex_classes(true),
91 'g' => {
::core::panicking::panic_fmt(format_args!("the global flag is unsupported by this implementation, please read the docs on the methods available on the Regex trait"));
}panic!("the global flag is unsupported by this implementation, please read \
92 the docs on the methods available on the Regex trait"),
93 o => {
::core::panicking::panic_fmt(format_args!("unknown flag provided for regex: {0:?}",
o));
}panic!("unknown flag provided for regex: {o:?}"),
94 };
95 }
96
97 config
98 }
99}
100
101impl Display for Flags {
102 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
103 let mut vec: Vec<_> = self.0.iter().collect();
104 vec.sort();
105 f.write_fmt(format_args!("{0:?}", &vec[..]))write!(f, "{:?}", &vec[..])
106 }
107}