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 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
extern crate proc_macro; use proc_macro2::TokenStream; use quote::quote; use quote::*; macro_rules! state_attribute { ($fn:ident, $implement:ident, $derive:ident) => { #[proc_macro_attribute] pub fn $fn(attr: proc_macro::TokenStream, item: proc_macro::TokenStream) -> proc_macro::TokenStream { let attr = TokenStream::from(attr); let ast: syn::ItemFn = syn::parse(item).unwrap(); let mut tokens = TokenStream::new(); ast.block.to_tokens(&mut tokens); let expanded = quote!{ impl $implement for #attr { fn $fn(&mut self) #tokens } }; proc_macro::TokenStream::from(expanded) } #[proc_macro_derive($implement)] pub fn $derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let ast: syn::DeriveInput = syn::parse(input).unwrap(); let name = &ast.ident; let expanded = quote! { impl $implement for #name { fn $fn(&mut self) {} } }; proc_macro::TokenStream::from(expanded) } }; } state_attribute!(on_start, OnStart, derive_on_start); state_attribute!(on_stop, OnStop, derive_on_stop); #[proc_macro_attribute] pub fn on_event(attr: proc_macro::TokenStream, item: proc_macro::TokenStream) -> proc_macro::TokenStream { let attr = TokenStream::from(attr); let ast: syn::ItemFn = syn::parse(item).unwrap(); let mut tokens = TokenStream::new(); ast.block.to_tokens(&mut tokens); let expanded = quote!{ impl OnEvent for #attr { fn on_event(&mut self, window: &mut Window, events: &mut EventsLoop) #tokens } }; proc_macro::TokenStream::from(expanded) } #[proc_macro_derive(OnEvent)] pub fn derive_on_event(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let ast: syn::DeriveInput = syn::parse(input).unwrap(); let name = &ast.ident; let expanded = quote! { impl OnEvent for #name { fn on_event(&mut self, window: &mut Window, events: &mut EventsLoop) {} } }; proc_macro::TokenStream::from(expanded) } #[proc_macro_attribute] pub fn on_update(attr: proc_macro::TokenStream, item: proc_macro::TokenStream) -> proc_macro::TokenStream { let attr = TokenStream::from(attr); let ast: syn::ItemFn = syn::parse(item).unwrap(); let mut tokens = TokenStream::new(); ast.block.to_tokens(&mut tokens); let expanded = quote!{ impl OnUpdate for #attr { fn on_update(&mut self, elapsed: u128, window: &mut Window) #tokens } }; proc_macro::TokenStream::from(expanded) } #[proc_macro_derive(OnUpdate)] pub fn derive_on_update(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let ast: syn::DeriveInput = syn::parse(input).unwrap(); let name = &ast.ident; let expanded = quote! { impl OnUpdate for #name { fn on_update(&mut self, elapsed: u128, window: &mut Window) {} } }; proc_macro::TokenStream::from(expanded) }