makeup_macros/
lib.rs

1use quote::quote;
2
3#[doc(hidden)]
4#[proc_macro]
5pub fn __do_check_mail_arms(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
6    let input = syn::parse::<syn::Expr>(input).expect("Failed to parse input");
7
8    let mut left_patterns = Vec::new();
9    let mut right_patterns = Vec::new();
10    let mut left_arms = Vec::new();
11    let mut right_arms = Vec::new();
12
13    if let syn::Expr::Group(group) = input {
14        if let syn::Expr::Match(expr_match) = group.expr.as_ref() {
15            for arm in expr_match.arms.iter() {
16                let pattern = arm.pat.clone();
17                let handler = arm.body.clone();
18
19                // If pattern is an ident starting with MakeupMessage::, put it in the right arm.
20                // Otherwise, put it in the left arm.
21
22                let is_makeup_message = match &pattern {
23                    syn::Pat::TupleStruct(ref pat_tuple_struct) => pat_tuple_struct.path.segments
24                        [0]
25                    .ident
26                    .to_string()
27                    .starts_with("MakeupMessage"),
28                    _ => false,
29                };
30
31                if is_makeup_message {
32                    right_patterns.push(pattern.clone());
33                    right_arms.push(handler);
34                } else {
35                    left_patterns.push(pattern.clone());
36                    left_arms.push(handler);
37                }
38            }
39        }
40    }
41    let output = quote! {
42        match message {
43            #(Either::Left(#left_patterns) => #left_arms)*
44            #(Either::Right(#right_patterns) => #right_arms)*
45            _ => {}
46        }
47    };
48
49    output.into()
50}