1#![deny(clippy::all)]
2
3extern crate proc_macro;
4extern crate proc_macro2;
5extern crate quote;
6extern crate syn;
7
8use proc_macro::TokenStream;
9use quote::{quote, quote_spanned};
10use syn::spanned::Spanned;
11use syn::{parse_macro_input, ItemFn};
12
13#[proc_macro_attribute]
14pub fn main(_attr: TokenStream, item: TokenStream) -> TokenStream {
15 let func = parse_macro_input!(item as ItemFn);
16 let func_ident = &func.sig.ident;
17
18 if func.sig.asyncness.is_none() {
19 return quote_spanned! { func.sig.span() =>
20 compile_error!{"The #[craydate::main] function must be async."}
21 }
22 .into();
23 }
24
25 quote!{
26 mod __main {
27 use super::*;
28 use ::alloc::boxed::Box;
29 use ::core::pin::Pin;
30 use ::core::future::Future;
31 use ::craydate::macro_helpers::__private::*;
32
33 #[no_mangle]
34 extern "C" fn eventHandler(eh1: EventHandler1, eh2: EventHandler2, eh3: EventHandler3) -> i32 {
35 fn main_wrapper(api: ::craydate::Api) -> Pin<Box<dyn Future<Output = !>>> {
36 Box::pin(#func_ident(api))
37 }
38 let config = GameConfig {
39 main_fn: main_wrapper,
40 };
41 event_handler(eh1, eh2, eh3, config);
42 0 }
44
45 #[cfg(all(target_arch = "arm", target_os = "none"))]
46 type EventHandlerFn = extern "C" fn(EventHandler1, EventHandler2, EventHandler3) -> i32;
47
48 #[cfg(all(target_arch = "arm", target_os = "none"))]
49 #[used]
50 #[link_section = ".capi_handler"]
51 static EVENT_HANDLER: EventHandlerFn = eventHandler;
52
53 #func
54 }
55 }.into()
56}