use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, Expr, ItemFn};
#[proc_macro_attribute]
pub fn alien_event(args: TokenStream, input: TokenStream) -> TokenStream {
let event_expr = parse_macro_input!(args as Expr);
let input_fn = parse_macro_input!(input as ItemFn);
let fn_vis = &input_fn.vis;
let fn_sig = &input_fn.sig;
let fn_block = &input_fn.block;
let fn_attrs = &input_fn.attrs;
let is_async = fn_sig.asyncness.is_some();
if is_async {
let expanded = quote! {
#(#fn_attrs)*
#fn_vis #fn_sig {
(#event_expr).in_scope(|_event_handle| async move #fn_block).await
}
};
TokenStream::from(expanded)
} else {
panic!("alien_event macro currently only supports async functions. Use AlienEvent::emit() manually for sync functions.");
}
}
mod controller;
use controller::{controller_impl, controller_struct};
#[proc_macro_attribute]
pub fn controller(args: TokenStream, input: TokenStream) -> TokenStream {
if syn::parse::<syn::ItemStruct>(input.clone()).is_ok() {
return controller_struct(args, input);
}
if syn::parse::<syn::ItemImpl>(input.clone()).is_ok() {
return controller_impl(args, input);
}
panic!("controller macro can only be applied to structs or impl blocks");
}
#[proc_macro_attribute]
pub fn flow_entry(_args: TokenStream, input: TokenStream) -> TokenStream {
input
}
#[proc_macro_attribute]
pub fn handler(_args: TokenStream, input: TokenStream) -> TokenStream {
input
}
#[proc_macro]
pub fn terminal_state(_input: TokenStream) -> TokenStream {
quote::quote! {}.into()
}