absinthe_macros/
lib.rs

1//! # Absinthe Macros
2//! 
3//! Absinthe Macros is a library that provides macros for Absinthe.
4//! 
5//! ## Features
6//! 
7//! - **actor!** - The actor! macro can be used to 'actorize' functions & structs.
8//! - **send!** - The send! macro can be used to send a message to an actor, and wait for a response.
9//! - **notify!** - The notify! macro can be used to send a message to an actor, and don't wait for a response.
10//! 
11
12/// Module used for Absinthe's own development.
13mod dev;
14
15/// send! and notify! argument parsing.
16mod msg;
17
18/// actor! parsing and actorization.
19mod actorizer;
20
21
22use actorizer::function::ActorizeFn;
23use actorizer::structure::ActorizeStruct;
24use dev::prelude::*;
25use syn::File;
26
27
28/// Send a message to an actor, and wait for a response.
29#[proc_macro]
30pub fn send(input: TokenStream) -> TokenStream {
31    let MsgSend { actor, payload } = parse_macro_input!(input as MsgSend);
32
33    let payload = if payload.len() == 0 {
34        quote!(())
35    } else {
36        quote!((#(#payload),*))
37    };
38
39    let expanded = quote! {
40        #actor.send_msg(#payload)
41    };
42
43    expanded.into()
44}
45
46/// Send a message to an actor, and don't wait for a response.
47#[proc_macro]
48pub fn notify(input: TokenStream) -> TokenStream {
49    let MsgSend { actor, payload } = parse_macro_input!(input as MsgSend);
50
51    let payload = if payload.len() == 0 {
52        quote!(())
53    } else {
54        quote!((#(#payload),*))
55    };
56
57    let expanded = quote! {
58        #actor.notify_msg(#payload)
59    };
60
61    expanded.into()
62}
63
64/// Create an actor.
65/// Can be used on a struct or a function.
66/// If actorizing a struct, the struct must have an `impl` block.
67/// The `impl` block must have the same name as the struct.
68#[proc_macro]
69pub fn actor(input: TokenStream) -> TokenStream {
70    let section = input.clone();
71    let section = parse_macro_input!(section as File);
72
73    match section.items.first().unwrap() {
74        Item::Struct(_) => {
75            parse_macro_input!(input as ActorizeStruct).into()
76        },
77        Item::Fn(_) => {
78            parse_macro_input!(input as ActorizeFn).into()
79
80        },
81        _ => syn::Error::new_spanned::<TokenStream2, _>(input.into(), "Expected `struct` or `fn`").to_compile_error().into()
82    }
83}