use crate::{ import::*, BoxEnvelope };
pub trait Envelope<A> where A: Actor, Self: Send
{
#[ must_use = "Futures do nothing unless polled" ]
fn handle( self: Box<Self>, actor: &mut A ) -> Return<'_, ()> where A: Send;
#[ must_use = "Futures do nothing unless polled" ]
fn handle_local( self: Box<Self>, actor: &mut A ) -> ReturnNoSend<'_, ()>;
}
pub(crate) struct SendEnvelope<M> where M: Message
{
msg: M,
}
impl<M> SendEnvelope<M> where M: Message
{
pub(crate) fn new( msg: M ) -> Self
{
Self { msg }
}
}
impl<A, M> Envelope<A> for SendEnvelope<M>
where A: Actor + Handler<M>,
M: Message ,
{
fn handle( self: Box<Self>, actor: &mut A ) -> Return<'_, ()>
{
< A as Handler<M> >::handle( actor, self.msg )
.map( |_|() )
.boxed()
}
fn handle_local( self: Box<Self>, actor: &mut A ) -> ReturnNoSend<'_, ()>
{
< A as Handler<M> >::handle_local( actor, self.msg )
.map( |_|() )
.boxed_local()
}
}
pub(crate) struct CallEnvelope<M> where M: Message
{
msg : M,
addr: OneSender< M::Return >,
}
impl<M> CallEnvelope<M> where M: Message
{
pub(crate) fn new( msg: M, addr: OneSender< M::Return > ) -> Self
{
Self { msg, addr }
}
}
impl<A, M> Envelope<A> for CallEnvelope<M>
where A: Actor ,
M: Message ,
A: Handler<M> ,
{
fn handle( self: Box<Self>, actor: &mut A ) -> Return<'_, ()>
{
let CallEnvelope { msg, addr } = *self;
let fut = < A as Handler<M> >::handle( actor, msg );
async move
{
if addr.send( fut.await ).is_err()
{
debug!( "failed to send from envelope, Addr already dropped?" );
}
}.boxed()
}
fn handle_local( self: Box<Self>, actor: &mut A ) -> ReturnNoSend<'_, ()>
{
let CallEnvelope { msg, addr } = *self;
let fut = < A as Handler<M> >::handle_local( actor, msg );
async move
{
if addr.send( fut.await ).is_err()
{
debug!( "failed to send from envelope, Addr already dropped?" );
}
}.boxed_local()
}
}
impl<A> fmt::Debug for BoxEnvelope<A>
{
fn fmt( &self, f: &mut fmt::Formatter<'_> ) -> fmt::Result
{
write!( f, "BoxEnvelope<{}>", std::any::type_name::<A>() )
}
}