1use proc_macro::TokenStream;
2use syn::parse_macro_input;
3
4use ab_code_gen::Config;
5use ab_code_gen::*;
6
7#[proc_macro_attribute]
18pub fn actor_module(args: TokenStream, input: TokenStream) -> TokenStream {
19 let parser = syn::punctuated::Punctuated::<syn::Expr, syn::Token![,]>::parse_terminated;
20 let args: syn::punctuated::Punctuated<syn::Expr, syn::token::Comma> =
21 parse_macro_input!(args with parser);
22 let config = get_config(args);
23 if let Err(e) = config {
24 return e.to_compile_error().into();
25 }
26 let config = config.unwrap();
27 let mut input = parse_macro_input!(input as syn::ItemMod);
28 let module = ActorModule::new(&input, &config);
29 if let Err(e) = module {
30 return e.to_compile_error().into();
31 }
32
33 let res = module.unwrap().generate();
34 if let Err(e) = res {
35 return e.to_compile_error().into();
36 }
37 let code_to_add = res.unwrap();
38 input
39 .content
40 .as_mut()
41 .unwrap()
42 .1
43 .push(syn::Item::Verbatim(code_to_add));
44 quote::quote! {#input}.into()
45}
46
47fn get_config(
48 args: syn::punctuated::Punctuated<syn::Expr, syn::token::Comma>,
49) -> syn::Result<Config> {
50 let mut config = Config::default();
51
52 for arg in args {
53 match arg {
54 syn::Expr::Assign(expr_assign) => match expr_assign.left.as_ref() {
55 syn::Expr::Path(expr_path) => {
56 let ident = expr_path.path.get_ident().unwrap();
57 match ident.to_string().as_str() {
58 "channels_size" => {
59 config.channels_size = parse_usize(&expr_assign.right)?;
60 }
61 "events_chan_size" => {
62 config.events_chan_size = parse_usize(&expr_assign.right)?;
63 }
64 _ => {
65 return Err(syn::Error::new_spanned(ident,
66 "Unsupported argument.\nSupported arguments are: \n- `channels_size`\n- `events_chan_size`"));
67 }
68 }
69 }
70 _ => {
71 return Err(syn::Error::new_spanned(
72 expr_assign.left,
73 "Invalid argument",
74 ))
75 }
76 },
77 _ => return Err(syn::Error::new_spanned(arg, "Invalid argument")),
78 }
79 }
80 Ok(config)
81}
82
83#[proc_macro_attribute]
85pub fn actor(args: TokenStream, input: TokenStream) -> TokenStream {
86 let _ = args;
87 let _ = input;
88 input
89}
90
91#[proc_macro_attribute]
97pub fn events(args: TokenStream, input: TokenStream) -> TokenStream {
98 let _ = args;
99 let _ = input;
100 input
101}
102
103#[proc_macro_attribute]
105pub fn message_handler(args: TokenStream, input: TokenStream) -> TokenStream {
106 let _ = args;
107 let _ = input;
108 input
109}
110
111fn parse_usize(expr: &syn::Expr) -> syn::Result<usize> {
112 match expr {
113 syn::Expr::Lit(expr_lit) => match &expr_lit.lit {
114 syn::Lit::Int(lit_int) => {
115 let value = lit_int.base10_parse::<usize>();
116 match value {
117 Ok(v) => Ok(v),
118 Err(_) => Err(syn::Error::new_spanned(
119 lit_int,
120 "Invalid value, literal usize expected.",
121 )),
122 }
123 }
124 _ => Err(syn::Error::new_spanned(expr_lit, "Invalid value")),
125 },
126 _ => Err(syn::Error::new_spanned(
127 expr,
128 "Invalid expression, `key=value` expected.",
129 )),
130 }
131}