1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
//! # acktor-derive
//!
//! Derive macros for the [`acktor`](https://github.com/asymmetry/acktor) actor framework.
use TokenStream;
/// Derive the [`Message`] trait for a struct or enum.
///
/// A `#[result_type(..)]` attribute must be present to specify the type returned when the message
/// is handled by an actor.
///
/// # Examples
///
/// ```ignore
/// use acktor_derive::{Message, MessageResponse};
///
/// #[derive(MessageResponse)]
/// struct Sum(i64);
///
/// #[derive(Message)]
/// #[result_type(Sum)]
/// struct Add(i64, i64);
/// ```
///
/// [`Message`]: https://docs.rs/acktor/latest/acktor/message/trait.Message.html
/// Derive the [`MessageResponse`] trait for a struct or enum.
///
/// This implements the default response handling, which sends the value back through an oneshot
/// channel to the sender of the message.
///
/// # Examples
///
/// ```ignore
/// use acktor_derive::MessageResponse;
///
/// #[derive(MessageResponse)]
/// struct Sum(i64);
///
/// #[derive(Message)]
/// #[result_type(Sum)]
/// struct Add(i64, i64);
/// ```
///
/// [`MessageResponse`]: https://docs.rs/acktor/latest/acktor/message/trait.MessageResponse.html
/// Derive the [`StableId`] trait for a type.
///
/// The generated `TYPE_ID` is the first 16 bytes of the SHA-256 digest of the type's
/// fully-qualified path (`module_path!() + "::" + ident`).
///
/// If the type contains type generic parameters, the generated `TYPE_ID` is combined with each
/// type generic parameter's `TYPE_ID` with [`StableTypeId::combine`] in their declaration order.
///
/// If the type contains const generic parameters, the generated `TYPE_ID` is combined with the
/// first 16 bytes of the SHA-256 digest of the big-endian form of each const generic parameter
/// with [`StableTypeId::combine`] in their declaration order.
///
/// # Example
///
/// ```ignore
/// use acktor_derive::StableId;
///
/// #[derive(StableId)]
/// struct Ping(u64);
/// ```
///
/// [`StableId`]: https://docs.rs/acktor/latest/acktor/stable_type_id/trait.StableId.html
/// [`StableTypeId::combine`]: https://docs.rs/acktor/latest/acktor/stable_type_id/struct.StableTypeId.html#method.combine
/// Derive the [`MessageId`] trait for a [`Message`].
///
/// By default, the derive also emits a [`StableId`] impl and sets
/// `MessageId::ID = StableId::TYPE_ID.as_u64()`. In this case, do **not** also derive
/// [`StableId`] separately, as that would produce conflicting impls. See derive macro
/// [`StableId`][macro@StableId] for the hashing scheme and the rules around generic parameters.
///
/// An optional `#[custom_id(<u64 value>)]` attribute lets the user supply the id directly. When
/// present, no [`StableId`] impl is emitted, and it is the user's responsibility to ensure the
/// id is unique across all messages an actor can handle.
///
/// # Example
///
/// ```ignore
/// use acktor_derive::MessageId;
///
/// #[derive(MessageId)]
/// struct Ping(u64);
///
/// #[derive(MessageId)]
/// #[custom_id(0xdead_beef)]
/// struct Pong;
/// ```
///
/// [`MessageId`]: https://docs.rs/acktor/latest/acktor/message/trait.MessageId.html
/// [`Message`]: https://docs.rs/acktor/latest/acktor/message/trait.Message.html
/// [`StableId`]: https://docs.rs/acktor/latest/acktor/stable_type_id/trait.StableId.html
/// Derive the [`Encode`] trait for a message.
///
/// A `#[codec(..)]` attribute must be present to select the serialization method and the same
/// attribute is shared with [`Decode`]. Encoding and decoding of the same message type must use
/// the same method. The attribute also supports an optional bridge type that serves as an
/// intermediary for encoding and decoding, which is useful when the message type itself cannot
/// directly implement the required traits. Currently there are three supported codec methods:
///
/// - `#[codec(prost)]` — delegates to [`prost::Message::encode_to_vec`]. The target type (or the
/// bridge type) must implement [`prost::Message`].
/// - `#[codec(serde_json)]` — delegates to [`serde_json::to_vec`]. The target type (or the bridge
/// type) must implement [`serde::Serialize`].
/// - `#[codec(zerocopy)]` — delegates to [`zerocopy::IntoBytes::as_bytes`]. The target type (or
/// the bridge type) must implement [`zerocopy::IntoBytes`].
/// - `#[codec(rkyv)]` — delegates to [`rkyv::to_bytes`]. The target type (or the bridge type)
/// must implement [`rkyv::Serialize`].
///
/// If a bridge type `T` is specified, the bridge type must be convertible from the target type
/// with `impl From<&Self> for T`.
///
/// # Example
///
/// ```ignore
/// use acktor_derive::Encode;
///
/// #[derive(zerocopy::IntoBytes, Encode)]
/// #[codec(zerocopy)]
/// struct Ping(u64);
/// ```
///
/// [`Encode`]: https://docs.rs/acktor/latest/acktor/codec/trait.Encode.html
/// [`Decode`]: https://docs.rs/acktor/latest/acktor/codec/trait.Decode.html
/// [`prost::Message`]: https://docs.rs/prost/latest/prost/trait.Message.html
/// [`prost::Message::encode_to_vec`]: https://docs.rs/prost/latest/prost/trait.Message.html#method.encode_to_vec
/// [`serde::Serialize`]: https://docs.rs/serde/latest/serde/ser/trait.Serialize.html
/// [`serde_json::to_vec`]: https://docs.rs/serde_json/latest/serde_json/fn.to_vec.html
/// [`zerocopy::IntoBytes`]: https://docs.rs/zerocopy/latest/zerocopy/trait.IntoBytes.html
/// [`zerocopy::IntoBytes::as_bytes`]: https://docs.rs/zerocopy/latest/zerocopy/trait.IntoBytes.html#method.as_bytes
/// [`rkyv::to_bytes`]: https://docs.rs/rkyv/latest/rkyv/fn.to_bytes.html
/// [`rkyv::Serialize`]: https://docs.rs/rkyv/latest/rkyv/trait.Serialize.html
/// Derive the [`Decode`] trait for a message.
///
/// A `#[codec(..)]` attribute must be present to select the deserialization method and the same
/// attribute is shared with [`Decode`]. Encoding and decoding of the same message type must use
/// the same method. The attribute also supports an optional bridge type that serves as an
/// intermediary for encoding and decoding, which is useful when the message type itself cannot
/// directly implement the required traits. Currently there are three supported codec methods:
///
/// - `#[codec(prost)]` — delegates to [`prost::Message::decode`]. The target type (or the bridge
/// type) must implement [`prost::Message`].
/// - `#[codec(serde_json)]` — delegates to [`serde_json::from_slice`]. The target type (or the
/// bridge type) must implement [`serde::Deserialize`].
/// - `#[codec(zerocopy)]` — delegates to [`zerocopy::FromBytes::read_from_bytes`]. The target
/// type (or the bridge type) must implement [`zerocopy::FromBytes`].
/// - `#[codec(rkyv)]` — delegates to [`rkyv::from_bytes`]. The target type (or the bridge type)
/// must implement [`rkyv::Archive`] and [`rkyv::Deserialize`].
///
/// If a bridge type `T` is specified, the target type must be convertible from the bridge type
/// with `impl TryFrom<T> for Self` and use [`DecodeError`] as the error type.
///
/// # Example
///
/// ```ignore
/// use acktor_derive::Decode;
///
/// #[derive(zerocopy::FromBytes, Decode)]
/// #[codec(zerocopy)]
/// struct Ping(u64);
/// ```
///
/// [`Encode`]: https://docs.rs/acktor/latest/acktor/codec/trait.Encode.html
/// [`Decode`]: https://docs.rs/acktor/latest/acktor/codec/trait.Decode.html
/// [`prost::Message`]: https://docs.rs/prost/latest/prost/trait.Message.html
/// [`prost::Message::decode`]: https://docs.rs/prost/latest/prost/trait.Message.html#method.decode
/// [`serde::Deserialize`]: https://docs.rs/serde/latest/serde/de/trait.Deserialize.html
/// [`serde_json::from_slice`]: https://docs.rs/serde_json/latest/serde_json/fn.from_slice.html
/// [`zerocopy::FromBytes`]: https://docs.rs/zerocopy/latest/zerocopy/trait.FromBytes.html
/// [`zerocopy::FromBytes::read_from_bytes`]: https://docs.rs/zerocopy/latest/zerocopy/trait.FromBytes.html#method.read_from_bytes
/// [`rkyv::from_bytes`]: https://docs.rs/rkyv/latest/rkyv/fn.from_bytes.html
/// [`rkyv::Archive`]: https://docs.rs/rkyv/latest/rkyv/trait.Archive.html
/// [`rkyv::Deserialize`]: https://docs.rs/rkyv/latest/rkyv/trait.Deserialize.html
/// [`DecodeError`]: https://docs.rs/acktor-ipc/latest/acktor_ipc/errors/enum.DecodeError.html
/// Derive the [`RemoteAddressable`] trait for an actor.
///
/// A `#[message(M1, M2, ...)]` attribute must be present to specify the list of messages the
/// actor can handle remotely. For each message `Mi`, the actor must have implemented the
/// [`Handler`] trait; `Mi` itself must have implemented the [`MessageId`] trait, the [`Encode`]
/// trait and the [`Decode`] trait; `Mi::Result` must also have implemented the [`Encode`] trait
/// and the [`Decode`] trait.
///
/// The macro emits a [`Codec`] impl and a `Handler<BinaryMessage>` impl for the actor based on
/// the message list specified in the `#[message(..)]` attribute. The [`Codec`] impl provides a
/// codec table which defines how to encode the message and decode the message response for each
/// message type `Mi`. The `Handler<BinaryMessage>` impl dispatches inbound messages by matching
/// the message id and invoking the corresponding message handler.
///
/// # Example
///
/// ```ignore
/// use acktor_derive::RemoteAddressable;
///
/// #[derive(RemoteAddressable)]
/// #[message(Ping, Echo)]
/// pub struct MyActor;
/// ```
///
/// [`RemoteAddressable`]: https://docs.rs/acktor/latest/acktor/actor/remote/trait.RemoteAddressable.html
/// [`Handler`]: https://docs.rs/acktor/latest/acktor/message/trait.Handler.html
/// [`MessageId`]: https://docs.rs/acktor/latest/acktor/message/index/trait.MessageId.html
/// [`Encode`]: https://docs.rs/acktor/latest/acktor/codec/trait.Encode.html
/// [`Decode`]: https://docs.rs/acktor/latest/acktor/codec/trait.Decode.html
/// [`Codec`]: https://docs.rs/acktor/latest/acktor/codec/table/trait.Codec.html
/// Attribute macro applies to the `impl Actor for MyActor` block, which overrides the internal
/// method `Actor::remote_mailbox` to return a [`RemoteMailbox`] for a remote addressable actor.
///
/// This is a temporary workaround since specialization is not yet stable in Rust.
///
/// # Example
///
/// ```ignore
/// use acktor_derive::remote;
///
/// #[remote]
/// impl Actor for MyActor {
/// type Error = anyhow::Error;
/// type Context = Context<Self>;
/// }
/// ```
///
/// [`RemoteMailbox`]: https://docs.rs/acktor/latest/acktor/address/type.RemoteMailbox.html