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 core_count = num_cpus::get();
21
22    let block = &input_fn.block;
23    let attrs = &input_fn.attrs;
24    let vis = &input_fn.vis;
25    let sig = &input_fn.sig;
26
27    let expanded = quote! {
28        #(#attrs)*
29        #vis #sig {
30            use std::error::Error;
31
32            let rt = bolt_web::tokio::runtime::Builder::new_multi_thread()
33                .worker_threads(#core_count)
34                .enable_all()
35                .build()
36                .unwrap();
37
38            let result: Result<(), Box<dyn Error + Send + Sync>> = rt.block_on(async move {
39                #block
40            });
41
42
43            if let Err(e) = result {
44                eprintln!("Bolt Web Application Error: {}", e);
45                ::std::process::exit(1);
46            }
47
48            Ok(())
49
50        }
51    };
52
53    expanded.into()
54}