ab_code_gen/
lib.rs

1mod actor;
2mod actor_messages;
3mod actor_proxy;
4mod module;
5mod utils;
6
7pub use actor::*;
8pub use actor_messages::*;
9pub use actor_proxy::*;
10pub use module::*;
11
12use convert_case::Casing;
13use syn::ReturnType;
14
15/// Configuration for the code generator
16pub struct Config {
17    pub channels_size: usize,
18    pub events_chan_size: usize,
19}
20
21impl Default for Config {
22    fn default() -> Self {
23        Config {
24            channels_size: 10,
25            events_chan_size: 10,
26        }
27    }
28}
29
30#[derive(Clone)]
31pub struct MessageHandlerMethod<'a> {
32    original: &'a syn::ImplItemFn,
33    parameters: Vec<(&'a syn::Ident, &'a syn::Type)>,
34}
35
36impl<'b> MessageHandlerMethod<'b> {
37    pub fn new(method: &syn::ImplItemFn) -> syn::Result<MessageHandlerMethod> {
38        // validate the method signature
39        let error = Err(syn::Error::new_spanned(
40            method,
41            "Message handler methods must have at least one parameter (&self)",
42        ));
43        if method.sig.inputs.is_empty() {
44            return error;
45        }
46        if let syn::FnArg::Receiver(rec) = method.sig.inputs.first().unwrap() {
47            if rec.reference.is_none() {
48                return error;
49            }
50        } else {
51            return error;
52        }
53
54        let parameters = method
55            .sig
56            .inputs
57            .iter()
58            .filter_map(|i| {
59                if let syn::FnArg::Typed(t) = i {
60                    if let syn::Pat::Ident(p) = t.pat.as_ref() {
61                        return Some((&p.ident, t.ty.as_ref()));
62                    }
63                }
64                None
65            })
66            .collect();
67
68        Ok(MessageHandlerMethod {
69            original: method,
70            parameters,
71        })
72    }
73
74    pub fn get_name_snake_case(&self) -> &syn::Ident {
75        &self.original.sig.ident
76    }
77
78    pub fn get_name_camel_case(&self) -> syn::Ident {
79        let name = self.get_name_snake_case();
80        syn::Ident::new(
81            &name.to_string().to_case(convert_case::Case::UpperCamel),
82            name.span(),
83        )
84    }
85
86    pub fn has_return_type(&self) -> bool {
87        matches!(self.original.sig.output, ReturnType::Type(_, _))
88    }
89
90    pub fn get_return_type(&self) -> Option<&'b syn::Type> {
91        match &self.original.sig.output {
92            ReturnType::Type(_, ty) => Some(ty),
93            _ => None,
94        }
95    }
96    pub fn get_parameter_names(&self) -> Vec<&syn::Ident> {
97        self.parameters.iter().map(|(name, _)| *name).collect()
98    }
99}