pfc_whitelist_derive/
lib.rs1use proc_macro::TokenStream;
2use quote::quote;
3use syn::{parse_macro_input, Attribute, DataEnum, DeriveInput};
4
5fn merge_variants(metadata: TokenStream, left: TokenStream, right: TokenStream) -> TokenStream {
11 use syn::Data::Enum;
12
13 let args = parse_macro_input!(metadata with Attribute::parse_outer);
14 if let Some(first_arg) = args.first() {
15 return syn::Error::new_spanned(first_arg, "macro takes no arguments")
16 .to_compile_error()
17 .into();
18 }
19
20 let mut left: DeriveInput = parse_macro_input!(left);
21 let right: DeriveInput = parse_macro_input!(right);
22
23 if let (
24 Enum(DataEnum {
25 variants,
26 ..
27 }),
28 Enum(DataEnum {
29 variants: to_add,
30 ..
31 }),
32 ) = (&mut left.data, right.data)
33 {
34 variants.extend(to_add);
35
36 quote! { #left }.into()
37 } else {
38 syn::Error::new(left.ident.span(), "variants may only be added for enums")
39 .to_compile_error()
40 .into()
41 }
42}
43
44#[proc_macro_attribute]
81pub fn pfc_whitelist_exec(metadata: TokenStream, input: TokenStream) -> TokenStream {
82 merge_variants(
83 metadata,
84 input,
85 quote! {
86 enum Right {
87 AddToWhiteList {address:String, reason:Option<String>},
89 RemoveFromWhitelist{address:String} ,
91 }
92 }
93 .into(),
94 )
95}
96#[proc_macro_attribute]
97pub fn pfc_whitelist_query(metadata: TokenStream, input: TokenStream) -> TokenStream {
98 merge_variants(
99 metadata,
100 input,
101 quote! {
102 enum Right {
103 #[returns(Option<::pfc_whitelist::Whitelist>)]
104 WhitelistEntry {address:String},
105 #[returns(::pfc_whitelist::WhitelistResponse<::pfc_whitelist::Whitelist>)]
106 Whitelist {start_after:Option<String>, limit: Option<u32>},
107 }
108 }
109 .into(),
110 )
111}