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
#![recursion_limit = "128"]
use proc_macro::TokenStream;
mod remote_actor;
mod remote_message;
// todo remove log dependency
// todo rename remotable to remoteactor
/// Helper to prepare actors for remote messages
/// # Example
/// ```
/// #[derive(Message, RemoteMessage)]
/// struct MyMessage {}
/// impl Sendable for MyMessage {}
/// // ...
///
/// #[derive(RemoteActor)]
/// #[remote_messages(MyMessage)]
/// struct MyActor {}
/// // ...
/// ```
///
/// # Background
///
/// In the previous example, the MyActor struct gets extended the following way:
///
/// ```
/// impl Handler<RemoteMessage> for MyActor {
/// type Result = ();
///
/// fn handle(&mut self, mut msg: RemoteMessage, ctx: &mut actix::prelude::Context<Self>) -> Self::Result {
/// if MyMessage::is_message(&(msg.message)) {
/// let deserialized_msg: MyMessage = MyMessage::from_packed(&(msg.message))
/// .expect("Cannot deserialized #name message");
/// ctx.address().do_send(deserialized_msg);
/// } else {
/// warn!("Message dropped because identifier of {} is unknown", &(msg.message));
/// }
/// }
/// }
/// ```
///
/// `remote_messages` can take multiple Message Types which get checked for their identifiers.
#[proc_macro_derive(RemoteActor, attributes(remote_messages, remote_ask_messages))]
pub fn remote_actor_macro(input: TokenStream) -> TokenStream {
remote_actor::remote_actor_macro(input)
}
/// Helper to make messages sendable over network
/// # Example
/// ```
/// #[derive(Message, Serialize, Deserialize, RemoteMessage)]
/// struct MyMessage {}
///
/// // ...
///
/// #[derive(RemoteActor)]
/// #[remote_messages(MyMessage)]
/// struct MyActor {}
/// // ...
/// ```
///
/// # Background
///
/// In the previous example, the MyMessage struct gets extended the following way:
///
/// ```
/// impl RemoteMessage for MyMessage {
/// type Serializer = DefaultSerialization;
/// const IDENTIFIER: &'static str = "MyMessage";
///
/// fn get_serializer(&self) -> Box<Self::Serializer> {
/// Box::new(DefaultSerialization {})
/// }
///
/// fn generate_serializer() -> Box<Self::Serializer> {
/// Box::new(DefaultSerialization {})
/// }
///
/// fn set_source(&mut self, addr: Addr<NetworkInterface>) {
///
/// }
/// }
/// ```
///
/// # Options
///
/// If you add the derive attribute `with_source`, you have the possibility to set the source remote address on a predefined struct attribute.
/// That attribute needs to have the following type: `RemoteAddr`
///
/// ## Example
/// ```
/// #[derive(Message, Serialize, Deserialize, RemoteMessage)]
/// #[with_source(source)]
/// struct MyMessage {
/// source: RemoteAddr
/// }
/// ```
///
#[proc_macro_derive(RemoteMessage, attributes(with_source))]
pub fn remote_message_macro(input: TokenStream) -> TokenStream {
remote_message::remote_message_macro(input)
}