macro_rules! impl_message_handler {
([$($generics:tt)*] for $actor_type:ty, [$($msg_type:ty),* $(,)?]) => { ... };
($actor_type:ty, [$($msg_type:ty),* $(,)?]) => { ... };
}Expand description
Implements the MessageHandler trait for both generic and non-generic actor types.
This macro simplifies the process of handling multiple message types within an actor.
It generates the necessary boilerplate code to downcast a Box<dyn Any + Send>
message to its concrete type and then calls the appropriate Message::handle
implementation on the actor.
§Usage
§For non-generic actors:
struct MyActor;
impl Actor for MyActor { /* ... */ }
struct Msg1;
struct Msg2;
impl Message<Msg1> for MyActor {
type Reply = ();
async fn handle(&mut self, msg: Msg1, _actor_ref: &ActorRef<Self>) -> Self::Reply { /* ... */ }
}
impl Message<Msg2> for MyActor {
type Reply = String;
async fn handle(&mut self, msg: Msg2, _actor_ref: &ActorRef<Self>) -> Self::Reply {
/* ... */ "response".to_string()
}
}
// This will implement `MessageHandler` for `MyActor`, allowing it to handle `Msg1` and `Msg2`.
impl_message_handler!(MyActor, [Msg1, Msg2]);§For generic actors:
struct GenericActor<T: Send + Debug + Clone + 'static> {
data: Option<T>,
}
impl<T: Send + Debug + Clone + 'static> Actor for GenericActor<T> { /* ... */ }
struct SetValue<T: Send + Debug + 'static>(T);
struct GetValue;
impl<T: Send + Debug + Clone + 'static> Message<SetValue<T>> for GenericActor<T> {
type Reply = ();
async fn handle(&mut self, msg: SetValue<T>, _actor_ref: &ActorRef<Self>) -> Self::Reply { /* ... */ }
}
impl<T: Send + Debug + Clone + 'static> Message<GetValue> for GenericActor<T> {
type Reply = Option<T>;
async fn handle(&mut self, msg: GetValue, _actor_ref: &ActorRef<Self>) -> Self::Reply { /* ... */ }
}
// This will implement `MessageHandler` for the generic `GenericActor<T>`.
impl_message_handler!([T: Send + Debug + Clone + 'static] for GenericActor<T>, [SetValue<T>, GetValue]);§Arguments
§Non-generic form:
$actor_type:ty: The type of the actor for which to implementMessageHandler.[$($msg_type:ty),* $(,)?]: A list of message types that the actor can handle.
impl_message_handler!(MyActor, [Msg1, Msg2]);§Generic form:
[$($generics:tt)*]: Generic type parameters with their trait bounds (as token tree to handle complex bounds)for $actor_type:ty: The generic actor type for which to implementMessageHandler[$($msg_type:ty),* $(,)?]: A list of message types that the actor can handle
impl_message_handler!([T: Send + Debug + Clone + 'static] for GenericActor<T>, [SetValue<T>, GetValue]);§Internals
This macro facilitates dynamic message dispatch by downcasting Box<dyn std::any::Any + Send>
message payloads to their concrete types at runtime. It implements the MessageHandler
trait for your actor, enabling it to handle multiple message types through the
handle method. The actual message handling logic
is generated by the internal __impl_message_handler_body! helper macro to avoid code
duplication between different implementation patterns.