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