1extern crate proc_macro;
2use proc_macro2::TokenStream;
3use quote::quote;
4use quote::*;
5
6macro_rules! state_attribute {
7 ($fn:ident, $implement:ident, $derive:ident) => {
8 #[proc_macro_attribute]
9 pub fn $fn(attr: proc_macro::TokenStream, item: proc_macro::TokenStream) -> proc_macro::TokenStream {
10 let attr = TokenStream::from(attr);
11 let ast: syn::ItemFn = syn::parse(item).unwrap();
12 let mut tokens = TokenStream::new();
13
14 ast.block.to_tokens(&mut tokens);
15 let expanded = quote!{
16 impl $implement for #attr {
17 fn $fn(&mut self) #tokens
18 }
19 };
20 proc_macro::TokenStream::from(expanded)
21 }
22
23 #[proc_macro_derive($implement)]
24 pub fn $derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
25 let ast: syn::DeriveInput = syn::parse(input).unwrap();
26 let name = &ast.ident;
27 let expanded = quote! {
28 impl $implement for #name {
29 fn $fn(&mut self) {}
30 }
31 };
32 proc_macro::TokenStream::from(expanded)
33 }
34 };
35}
36
37state_attribute!(on_start, OnStart, derive_on_start);
38state_attribute!(on_stop, OnStop, derive_on_stop);
39
40#[proc_macro_attribute]
41pub fn on_event(attr: proc_macro::TokenStream, item: proc_macro::TokenStream) -> proc_macro::TokenStream {
42 let attr = TokenStream::from(attr);
43 let ast: syn::ItemFn = syn::parse(item).unwrap();
44 let mut tokens = TokenStream::new();
45 ast.block.to_tokens(&mut tokens);
46 let expanded = quote!{
47 impl OnEvent for #attr {
48 fn on_event(&mut self, window: &mut Window, events: &mut EventsLoop) #tokens
49 }
50 };
51 proc_macro::TokenStream::from(expanded)
52}
53
54#[proc_macro_derive(OnEvent)]
55pub fn derive_on_event(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
56 let ast: syn::DeriveInput = syn::parse(input).unwrap();
57 let name = &ast.ident;
58 let expanded = quote! {
59 impl OnEvent for #name {
60 fn on_event(&mut self, window: &mut Window, events: &mut EventsLoop) {}
61 }
62 };
63 proc_macro::TokenStream::from(expanded)
64}
65
66#[proc_macro_attribute]
67pub fn on_update(attr: proc_macro::TokenStream, item: proc_macro::TokenStream) -> proc_macro::TokenStream {
68 let attr = TokenStream::from(attr);
69 let ast: syn::ItemFn = syn::parse(item).unwrap();
70 let mut tokens = TokenStream::new();
71 ast.block.to_tokens(&mut tokens);
72 let expanded = quote!{
73 impl OnUpdate for #attr {
74 fn on_update(&mut self, elapsed: u128, window: &mut Window) #tokens
75 }
76 };
77 proc_macro::TokenStream::from(expanded)
78}
79
80#[proc_macro_derive(OnUpdate)]
81pub fn derive_on_update(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
82 let ast: syn::DeriveInput = syn::parse(input).unwrap();
83 let name = &ast.ident;
84 let expanded = quote! {
85 impl OnUpdate for #name {
86 fn on_update(&mut self, elapsed: u128, window: &mut Window) {}
87 }
88 };
89 proc_macro::TokenStream::from(expanded)
90}