improv 1.0.0-beta.1

Actor microframework
Documentation
use super::prelude::*;

pub struct Addr<A: Actor> {
    inner: Arc<mpsc::UnboundedSender<Box<dyn Envelope<Actor = A>>>>,
}

impl<A: Actor> Addr<A> {
    #[inline]
    pub(super) fn new(
        tx: mpsc::UnboundedSender<Box<dyn Envelope<Actor = A>>>,
    ) -> Self {
        Self { inner: Arc::new(tx) }
    }
}

impl<A: Actor> Addr<A> {
    pub fn tell<M: Message<Response = ()>>(
        &self,
        msg: M,
    ) -> Result<(), Disconnected>
    where
        A: Receive<M>,
    {
        let teller = TellEnvelope::new(msg);
        self.inner.send(Box::new(teller)).map_err(|_| Disconnected::new())
    }

    pub fn ask<M: Message>(
        &self,
        msg: M,
    ) -> impl Future<Output = Result<<M as Message>::Response, Disconnected>> + 'static
    where
        A: Receive<M>,
    {
        let (asker, rx) = AskEnvelope::new(msg);
        let inner = Arc::clone(&self.inner);
        async move {
            inner.send(Box::new(asker)).map_err(|_| Disconnected::new())?;
            rx.await
        }
    }

    #[inline]
    pub fn into_teller<M: Message<Response = ()>>(self) -> Teller<M>
    where
        A: Receive<M>,
    {
        Teller::new(self)
    }

    #[inline]
    #[inline]
    pub fn into_asker<M: Message>(self) -> Asker<M>
    where
        A: Receive<M>,
    {
        Asker::new(self)
    }
}

impl<A: Actor, M: Message<Response = ()>> Tell<M> for Addr<A>
where
    A: Receive<M>,
{
    fn tell(&self, msg: M) -> Result<(), Disconnected> { self.tell(msg) }
}

impl<A: Actor, M: Message> Ask<M> for Addr<A>
where
    A: Receive<M>,
{
    fn ask(
        &self,
        msg: M,
    ) -> BoxFuture<'static, Result<<M as Message>::Response, Disconnected>>
    {
        self.ask(msg).boxed()
    }
}

impl<A: Actor> fmt::Debug for Addr<A> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "Address({:p})", self.inner)
    }
}

impl<A: Actor> Clone for Addr<A> {
    fn clone(&self) -> Self { Self { inner: Arc::clone(&self.inner) } }
}