rhachis_run_macro/
lib.rs

1#![doc = include_str!("../README.md")]
2use proc_macro::TokenStream;
3use proc_macro2::TokenTree;
4use quote::quote;
5
6#[proc_macro_attribute]
7pub fn run(attr: TokenStream, item: TokenStream) -> TokenStream {
8    let input = proc_macro2::TokenStream::from(item);
9    let attr = proc_macro2::TokenStream::from(attr);
10
11    let mut ident = None;
12    for item in input
13        .clone()
14        .into_iter()
15        .collect::<Vec<TokenTree>>()
16        .windows(2)
17    {
18        if let TokenTree::Ident(ident0) = &item[0] {
19            if ident0 == "struct" {
20                if let TokenTree::Ident(ident1) = &item[1] {
21                    ident = Some(ident1.clone());
22                    break;
23                }
24            }
25        }
26    }
27
28    let ident = ident.unwrap();
29    #[cfg(not(feature = "tokio"))]
30    let to_ret = if attr.is_empty() {
31        quote! {
32            fn main() {
33                #ident::run(rhachis::GameInit::default());
34            }
35            #input
36        }
37    } else {
38        quote! {
39            fn main() {
40                #ident::run(#attr);
41            }
42            #input
43        }
44    };
45    #[cfg(feature = "tokio")]
46    let to_ret = if attr.is_empty() {
47        quote! {
48            #[tokio::main]
49            pub async fn main() {
50                #ident::run(rhachis::GameInit::default());
51            }
52            #input
53        }
54    } else {
55        quote! {
56            #[tokio::main]
57            async fn main() {
58                #ident::run(#attr);
59            }
60            #input
61        }
62    };
63
64    proc_macro::TokenStream::from(to_ret)
65}