bolt_web_macro/
lib.rs

1use proc_macro::TokenStream;
2use quote::quote;
3use syn::{ItemFn, parse_macro_input};
4
5#[proc_macro_attribute]
6pub fn main(_attr: TokenStream, item: TokenStream) -> TokenStream {
7    let mut input_fn = parse_macro_input!(item as ItemFn);
8
9    if input_fn.sig.asyncness.is_none() {
10        return syn::Error::new_spanned(
11            &input_fn.sig.fn_token,
12            "The #[bolt_web::main] function must be async.",
13        )
14        .to_compile_error()
15        .into();
16    }
17
18    input_fn.sig.asyncness = None;
19
20    let block = &input_fn.block;
21    let attrs = &input_fn.attrs;
22    let vis = &input_fn.vis;
23    let sig = &input_fn.sig;
24
25    let expanded = quote! {
26        #(#attrs)*
27        #vis #sig {
28            use std::error::Error;
29            let core_count = ::num_cpus::get();
30
31            let rt = bolt_web::tokio::runtime::Builder::new_multi_thread()
32                .worker_threads(core_count)
33                .enable_all()
34                .build()
35                .unwrap();
36
37            let result: Result<(), Box<dyn Error + Send + Sync>> = rt.block_on(async move {
38                #block
39            });
40
41
42            if let Err(e) = result {
43                eprintln!("Bolt Web Application Error: {}", e);
44                ::std::process::exit(1);
45            }
46
47            Ok(())
48
49        }
50    };
51
52    expanded.into()
53}