bevy_mod_check_filter_macros/
lib.rs

1use proc_macro2::TokenStream;
2use quote::{quote, ToTokens};
3use syn::{parse_macro_input, DeriveInput, Ident};
4
5#[proc_macro_derive(IsVariant)]
6pub fn derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
7    // Parse the input tokens into a syntax tree
8    let input = parse_macro_input!(input as DeriveInput);
9
10    let enum_name = input.ident;
11    let vis = input.vis.to_token_stream();
12
13    let expanded: TokenStream = if let syn::Data::Enum(e) = input.data {
14        e.variants
15            .into_iter()
16            .map(|v| {
17                let ident = v.ident;
18                let name = Ident::new(&format!("Is{ident}"), ident.span());
19                let m = match v.fields {
20                    syn::Fields::Unit => quote! { #enum_name::#ident },
21                    _ => quote! { #enum_name::#ident { .. } },
22                };
23
24                quote! {
25                    #vis struct #name;
26
27                    impl bevy_mod_check_filter::Predicate<#enum_name> for #name {
28                        fn test(test: &#enum_name) -> bool {
29                            match *test {
30                              #m => true,
31                              _ => false,
32                            }
33                        }
34                    }
35                }
36            })
37            .collect()
38    } else {
39        panic!("IsVariant derive only works on Enums");
40    };
41
42    // Hand the output tokens back to the compiler
43    proc_macro::TokenStream::from(expanded)
44}