Add more ergonomic constructor of ActorHandles

Signed-off-by: Marcel Müller <neikos@neikos.email>
This commit is contained in:
Marcel Müller 2025-11-05 14:48:51 +01:00
parent d38b04396c
commit 023a2a17fc

View file

@ -7,10 +7,23 @@ use crate::IsContainedInBundle;
use crate::Message; use crate::Message;
use crate::MessageBundle; use crate::MessageBundle;
pub trait Actor: Any { pub trait Actor: Any
where
Self: ActorHandler<Self::HandledMessages>,
{
type HandledMessages: MessageBundle; type HandledMessages: MessageBundle;
} }
pub trait IntoActorHandle<MB> {
fn into_actor_handle(self) -> ActorHandle<MB>;
}
impl<A: Actor> IntoActorHandle<A::HandledMessages> for A {
fn into_actor_handle(self) -> ActorHandle<A::HandledMessages> {
ActorHandle::new(self)
}
}
pub trait Handle<M: Message> { pub trait Handle<M: Message> {
fn handle(&mut self, message: M) -> impl Future<Output = anyhow::Result<M::Reply>>; fn handle(&mut self, message: M) -> impl Future<Output = anyhow::Result<M::Reply>>;
} }
@ -26,7 +39,7 @@ macro_rules! impl_actor_handle {
( $($ty:ident),* ) => { ( $($ty:ident),* ) => {
impl<ACTOR, $($ty,)*> ActorHandler<($($ty,)*)> for ACTOR impl<ACTOR, $($ty,)*> ActorHandler<($($ty,)*)> for ACTOR
where where
ACTOR: Actor<HandledMessages = ($($ty,)*)>, ACTOR: Actor,
$( ACTOR: Handle<$ty>, )* $( ACTOR: Handle<$ty>, )*
$( $ty: Message, )* $( $ty: Message, )*
{ {
@ -40,7 +53,7 @@ macro_rules! impl_actor_handle {
$( $(
let msg = match msg.into_inner::<$ty>() { let msg = match msg.into_inner::<$ty>() {
Ok(msg) => { Ok(msg) => {
return self.handle(msg).await.map(InternalMessage::new); return <Self as Handle<$ty>>::handle(self, msg).await.map(InternalMessage::new);
} }
Err(msg) => msg, Err(msg) => msg,
}; };
@ -50,6 +63,7 @@ macro_rules! impl_actor_handle {
} }
} }
} }
}; };
} }
@ -112,12 +126,6 @@ mod tests {
type Reply = (); type Reply = ();
} }
struct Zap;
impl Message for Zap {
type Reply = ();
}
struct FActor; struct FActor;
impl Actor for FActor { impl Actor for FActor {
@ -126,14 +134,14 @@ mod tests {
impl Handle<Foo> for FActor { impl Handle<Foo> for FActor {
async fn handle(&mut self, _message: Foo) -> anyhow::Result<<Foo as Message>::Reply> { async fn handle(&mut self, _message: Foo) -> anyhow::Result<<Foo as Message>::Reply> {
todo!() Ok(())
} }
} }
#[apply(test!)] #[apply(test!)]
async fn test_name() { async fn test_name() {
let mut actor = ActorHandle::new(FActor); let mut actor = FActor.into_actor_handle();
actor.handle(Zap).await.unwrap(); actor.handle(Foo).await.unwrap();
} }
} }