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