use std::fmt;
pub(crate) mod channel;
mod envelope;
mod message;
mod queue;
use actor::Actor;
use handler::{Handler, Message};
pub use self::envelope::{Envelope, EnvelopeProxy, ToEnvelope};
pub use self::message::{RecipientRequest, Request};
pub(crate) use self::channel::AddressReceiver;
use self::channel::{AddressSender, Sender};
pub enum SendError<T> {
Full(T),
Closed(T),
}
#[derive(Fail)]
pub enum MailboxError {
#[fail(display = "Mailbox has closed")]
Closed,
#[fail(display = "Message delivery timed out")]
Timeout,
}
impl<T> SendError<T> {
pub fn into_inner(self) -> T {
match self {
SendError::Full(msg) | SendError::Closed(msg) => msg,
}
}
}
impl<T> fmt::Debug for SendError<T> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match *self {
SendError::Full(_) => write!(fmt, "SendError::Full(..)"),
SendError::Closed(_) => write!(fmt, "SendError::Closed(..)"),
}
}
}
impl<T> fmt::Display for SendError<T> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match *self {
SendError::Full(_) => write!(fmt, "send failed because receiver is full"),
SendError::Closed(_) => write!(fmt, "send failed because receiver is gone"),
}
}
}
impl fmt::Debug for MailboxError {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
write!(fmt, "MailboxError({})", self)
}
}
pub struct Addr<A: Actor> {
tx: AddressSender<A>,
}
impl<A: Actor> Addr<A> {
pub fn new(tx: AddressSender<A>) -> Addr<A> {
Addr { tx }
}
#[inline]
pub fn connected(&self) -> bool {
self.tx.connected()
}
#[inline]
pub fn do_send<M>(&self, msg: M)
where
M: Message + Send,
M::Result: Send,
A: Handler<M>,
A::Context: ToEnvelope<A, M>,
{
let _ = self.tx.do_send(msg);
}
#[inline]
pub fn send<M>(&self, msg: M) -> Request<A, M>
where
M: Message + Send,
M::Result: Send,
A: Handler<M>,
A::Context: ToEnvelope<A, M>,
{
match self.tx.send(msg) {
Ok(rx) => Request::new(Some(rx), None),
Err(SendError::Full(msg)) => {
Request::new(None, Some((self.tx.clone(), msg)))
}
Err(SendError::Closed(_)) => Request::new(None, None),
}
}
pub fn recipient<M: 'static>(self) -> Recipient<M>
where
A: Handler<M>,
A::Context: ToEnvelope<A, M>,
M: Message + Send,
M::Result: Send,
{
Recipient::new(Box::new(self.tx.clone()))
}
}
impl<A: Actor> Clone for Addr<A> {
fn clone(&self) -> Addr<A> {
Addr {
tx: self.tx.clone(),
}
}
}
pub struct Recipient<M: Message> {
tx: Box<Sender<M>>,
}
unsafe impl<M> Send for Recipient<M>
where
M: Message + Send,
M::Result: Send,
{
}
impl<M> Recipient<M>
where
M: Message + Send,
M::Result: Send,
{
pub(crate) fn new(tx: Box<Sender<M>>) -> Recipient<M> {
Recipient { tx }
}
pub fn do_send(&self, msg: M) -> Result<(), SendError<M>> {
self.tx.do_send(msg)
}
pub fn send(&self, msg: M) -> RecipientRequest<M> {
match self.tx.send(msg) {
Ok(rx) => RecipientRequest::new(Some(rx), None),
Err(SendError::Full(msg)) => {
RecipientRequest::new(None, Some((self.tx.boxed(), msg)))
}
Err(SendError::Closed(_)) => RecipientRequest::new(None, None),
}
}
}
impl<M> Clone for Recipient<M>
where
M: Message + Send,
M::Result: Send,
{
fn clone(&self) -> Recipient<M> {
Recipient {
tx: self.tx.boxed(),
}
}
}