lazy_regex_proc_macros/
args.rs

1use syn::{
2    parse::{
3        Parse,
4        ParseStream,
5        Result,
6    },
7    Expr,
8    ExprClosure,
9    LitStr,
10    Token,
11};
12
13/// Wrapping of the two arguments given to one of the
14/// `regex_is_match`, `regex_find`, or `regex_captures`
15/// macros
16pub(crate) struct RexValArgs {
17    pub regex_str: LitStr,
18    pub value: Expr, // this expression is (or produces) the text to search or check
19}
20
21impl Parse for RexValArgs {
22    fn parse(input: ParseStream<'_>) -> Result<Self> {
23        let regex_str = input.parse::<LitStr>()?;
24        input.parse::<Token![,]>()?;
25        let value = input.parse::<Expr>()?;
26        let _ = input.parse::<Token![,]>(); // allow a trailing comma
27        Ok(RexValArgs { regex_str, value })
28    }
29}
30
31/// Wrapping of the three arguments given to the
32/// ``regex_replace` and regex_replace_all` macros
33pub(crate) struct ReplaceArgs {
34    pub regex_str: LitStr,
35    pub value: Expr,
36    pub replacer: MaybeFun,
37}
38
39pub(crate) enum MaybeFun {
40    Fun(ExprClosure),
41    Expr(Expr),
42}
43
44impl Parse for ReplaceArgs {
45    fn parse(input: ParseStream<'_>) -> Result<Self> {
46        let regex_str = input.parse::<LitStr>()?;
47        input.parse::<Token![,]>()?;
48        let value = input.parse::<Expr>()?;
49        input.parse::<Token![,]>()?;
50        // we try as a closure before, and as a general expr if
51        // it doesn't work out
52        let replacer = if let Ok(fun) = input.parse::<ExprClosure>() {
53            MaybeFun::Fun(fun)
54        } else {
55            MaybeFun::Expr(input.parse::<Expr>()?)
56        };
57        let _ = input.parse::<Token![,]>(); // allow a trailing comma
58        Ok(ReplaceArgs {
59            regex_str,
60            value,
61            replacer,
62        })
63    }
64}
65
66/// Wrapping of the arguments given to a regex_if macro
67pub(crate) struct RexIfArgs {
68    pub regex_str: LitStr,
69    pub value: Expr, // this expression is (or produces) the text to search or check
70    pub then: Expr,
71}
72
73impl Parse for RexIfArgs {
74    fn parse(input: ParseStream<'_>) -> Result<Self> {
75        let regex_str = input.parse::<LitStr>()?;
76        input.parse::<Token![,]>()?;
77        let value = input.parse::<Expr>()?;
78        input.parse::<Token![,]>()?;
79        let then = input.parse::<Expr>()?;
80        let _ = input.parse::<Token![,]>(); // allow a trailing comma
81        Ok(Self {
82            regex_str,
83            value,
84            then,
85        })
86    }
87}
88
89/// Wrapping of the arguments given to a regex_switch macro
90pub(crate) struct RexSwitchArgs {
91    pub value: Expr, // this expression is (or produces) the text to search or check
92    pub arms: Vec<RexSwitchArmArgs>,
93}
94pub(crate) struct RexSwitchArmArgs {
95    pub regex_str: LitStr,
96    pub then: Expr,
97}
98
99impl Parse for RexSwitchArgs {
100    fn parse(input: ParseStream<'_>) -> Result<Self> {
101        let value = input.parse::<Expr>()?;
102        input.parse::<Token![,]>()?;
103        let mut arms = Vec::new();
104        loop {
105            let lookahead = input.lookahead1();
106            if lookahead.peek(LitStr) {
107                let arm = input.parse::<RexSwitchArmArgs>()?;
108                arms.push(arm);
109            } else {
110                break;
111            }
112        }
113        Ok(Self {
114            value,
115            arms,
116        })
117    }
118}
119impl Parse for RexSwitchArmArgs {
120    fn parse(input: ParseStream<'_>) -> Result<Self> {
121        let regex_str = input.parse::<LitStr>()?;
122        input.parse::<Token![=>]>()?;
123        let then = input.parse::<Expr>()?;
124        let _ = input.parse::<Token![,]>(); // allow a trailing comma
125        Ok(Self {
126            regex_str,
127            then,
128        })
129    }
130}