zestors_codegen/
lib.rs

1use proc_macro::TokenStream as TokenStream1;
2#[macro_use]
3extern crate quote;
4
5/// Derive the `Message` trait.
6///
7/// # Usage
8/// ```ignore
9/// #[derive(Message)]
10/// struct MyMessage;
11///
12/// #[derive(Message)]
13/// #[request(T)]
14/// struct MyRequest;
15/// 
16/// // (Same as the one above)
17/// #[derive(Message)]
18/// #[msg(Rx<T>)]
19/// struct MyRequest;
20/// ```
21/// 
22/// This generates the following implementation:
23/// ```ignore
24/// impl Message for MyMessage { ... }
25/// ```
26#[proc_macro_derive(Message, attributes(msg, request))]
27pub fn derive_message(item: TokenStream1) -> TokenStream1 {
28    message::derive_message(item.into())
29        .unwrap_or_else(|e| e.into_compile_error())
30        .into()
31}
32
33
34/// Modifies the enum to implement protocol:
35///
36/// # Usage
37/// ```ignore
38/// #[protocol]
39/// enum MyProtocol {
40///     MessageOne(Msg),
41///     MessageTwo(Request)
42/// }
43/// ```
44///
45/// Creates the following enum:
46/// ```ignore
47/// enum MyProtocol {
48///     MessageOne(Msg),
49///     MessageTwo((Request, Tx<T>))
50/// }
51/// ```
52///
53/// And also generates the following implementations:
54/// ```ignore
55/// impl Protocol for MyProtocol { ... }
56/// impl Accept<OneOffMsg> for MyProtocol { ... }
57/// impl Accept<MessageWithRequest> for MyProtocol { ... }
58/// impl<H: Handler> HandledBy<H> for MyProtocol
59/// where 
60///     H: HandleMessage<OneOffMsg> + HandleMessage<MessageWithRequest>
61/// { ... }
62/// ```
63#[proc_macro_attribute]
64pub fn protocol(attr: TokenStream1, item: TokenStream1) -> TokenStream1 {
65    protocol::protocol(attr.into(), item.into())
66        .unwrap_or_else(|e| e.into_compile_error())
67        .into()
68}
69
70/// Generates a trait that can be used to send `Envelope`s of this message.
71/// 
72/// # Usage
73/// ```ignore
74/// #[derive(Message, Envelope)]
75/// struct MyMessage {
76///     arg1: u32,
77///     arg2: u64
78/// }
79/// 
80/// #[derive(Message, Envelope)]
81/// #[envelope(CustomTraitName, custom_method_name)]
82/// struct MyMessage {
83///     arg1: u32,
84///     arg2: u64
85/// }
86/// ```
87/// 
88/// Which generates the a trait similar to the following:
89/// ```ignore
90/// trait MyMessageEnvelope {
91///     pub fn my_message(&self, arg1: u32, arg2: u64) -> Envelope<..> {
92///         ...
93///     }
94/// }
95/// 
96/// impl<T, A> MyMessageEnvelope for T 
97/// where 
98///     T: ActorRef<ActorType = A>,
99///     A: Accept<MyMessage>
100/// ```
101/// 
102/// This makes it possible to call `my_message` directly on an `Address` or `Child`.
103#[proc_macro_derive(Envelope, attributes(envelope))]
104pub fn derive_envelope(item: TokenStream1) -> TokenStream1 {
105    envelope::derive_envelope(item.into())
106        .unwrap_or_else(|e| e.into_compile_error())
107        .into()
108}
109
110/// Implements `HandleExit` for your `Handler`.
111/// 
112/// # Usage
113/// ```ignore
114/// #[derive(HandleExit)]
115/// struct MyHandler { .. }
116/// ```
117/// 
118/// Which generates the following implementation:
119/// ```ignore
120/// impl HandleExit for MyHandler {
121///     type Exit = ExitReason<MyHandler::Exception>;
122/// 
123///     async fn handle_exit(
124///         self,
125///         state: &mut Self::State,
126///         reason: ExitReason<Self::Exception>,
127///     ) -> ExitFlow<Self> {
128///         ExitFlow::Exit(reason)
129///     }
130/// }
131/// ```
132#[proc_macro_derive(Handler, attributes(state))]
133pub fn derive_handler(item: TokenStream1) -> TokenStream1 {
134    handler::derive_handler(item.into())
135        .unwrap_or_else(|e| e.into_compile_error())
136        .into()
137}
138
139mod message;
140mod protocol;
141mod envelope;
142mod handler;