1use crate::actor::Actor;
2use crate::message::MessageFor;
3use crate::runtime::Address;
4use anyhow::Error;
5use async_trait::async_trait;
6
7impl<T> Address<T> {
8 pub fn event<E>(&self, event: E) -> Result<(), Error>
9 where
10 T: OnEvent<E>,
11 E: Send + 'static,
12 {
13 self.send(Event::new(event))
14 }
15}
16
17#[async_trait]
18pub trait OnEvent<E>: Actor {
19 type Error: Into<Error> + Send + 'static;
20 async fn handle(&mut self, event: E, ctx: &mut Self::Context) -> Result<(), Self::Error>;
21
22 async fn fallback(&mut self, err: Self::Error, _ctx: &mut Self::Context) -> Result<(), Error> {
23 Err(err.into())
24 }
25}
26
27pub struct Event<E> {
28 event: E,
29}
30
31impl<E> Event<E> {
32 pub fn new(event: E) -> Self {
33 Self { event }
34 }
35}
36
37#[async_trait]
38impl<A, E> MessageFor<A> for Event<E>
39where
40 A: OnEvent<E>,
41 E: Send + 'static,
42{
43 async fn handle(self: Box<Self>, actor: &mut A, ctx: &mut A::Context) -> Result<(), Error> {
44 if let Err(err) = actor.handle(self.event, ctx).await {
45 actor.fallback(err, ctx).await
46 } else {
47 Ok(())
48 }
49 }
50}