1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
extern crate proc_macro; use proc_macro::TokenStream; use syn::{parse_macro_input, Data, DeriveInput, Ident}; #[macro_use] extern crate quote; #[proc_macro_derive(RelayGlobalID)] pub fn derive_relay_global_id(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input as DeriveInput); let name = input.ident; let m = quote! { impl #name { pub fn relay_id(&self) -> String { format!("{}{}", self.id, SchemaNodeTypes::#name as u32) } } }; TokenStream::from(m) } #[proc_macro_derive(RelayNodeEnum)] pub fn derive_relay_node(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input as DeriveInput); let name = input.ident; let variants = match input.data { Data::Enum(e) => e .variants .into_iter() .map(|v| v.ident) .collect::<Vec<Ident>>(), _ => { panic!("The RelayNode macro must be used on an enum type"); } }; let variant_node_type = (0..variants.len()).map(|v| (v + 1).to_string()); let m = quote! { pub enum SchemaNodeTypes { Unknown = 0, #( #variants, )* } impl #name { pub async fn get(relay_id: String) -> Option<Node> { if relay_id.len() < 36 { None? } let (id, node_type) = relay_id.split_at(36); match node_type { #( #variant_node_type => Some(<#variants>::get(id.to_string()).await), )* _ => None } } } }; TokenStream::from(m) }