use std::fmt;
use crate::protocol::*;
use crate::actor::{ActorUri, BoxActorProd, ActorCell, CellPublic};
use crate::actor::{Tell, TryTell, SysTell, CreateError, TryMsgError};
#[derive(Clone)]
pub struct ActorRef<Msg: Message> {
pub uri: ActorUri,
pub cell: ActorCell<Msg>
}
impl<Msg: Message> ActorRef<Msg> {
#[doc(hidden)]
pub fn new(uri: &ActorUri, cell: ActorCell<Msg>) -> ActorRef<Msg> {
ActorRef {
uri: uri.clone(),
cell: cell,
}
}
pub fn name(&self) -> &str {
&self.uri.name.as_str()
}
pub fn path(&self) -> &String {
&self.uri.path
}
pub fn is_root(&self) -> bool {
self.cell.is_root()
}
pub fn parent(&self) -> ActorRef<Msg> {
self.cell.parent()
}
pub fn user_root(&self) -> ActorRef<Msg> {
self.cell.user_root()
}
pub fn children<'a>(&'a self) -> Box<dyn Iterator<Item = ActorRef<Msg>> + 'a> {
self.cell.children()
}
}
impl<Msg: Message> Tell for ActorRef<Msg> {
type Msg = Msg;
#[allow(unused)]
fn tell<T>(&self,
msg: T,
sender: Option<ActorRef<Self::Msg>>)
where T: Into<ActorMsg<Self::Msg>>
{
let envelope = Envelope {
msg: msg.into(),
sender: sender,
};
let _ = self.cell.send_msg(envelope);
}
}
impl<Msg: Message> TryTell for Option<ActorRef<Msg>> {
type Msg = Msg;
fn try_tell<T>(&self,
msg: T,
sender: Option<ActorRef<Self::Msg>>) -> Result<(), TryMsgError<T>>
where T: Into<ActorMsg<Self::Msg>>
{
match self {
Some(ref actor) => {
let envelope = Envelope {
msg: msg.into(),
sender: sender,
};
let _ = actor.cell.send_msg(envelope);
Ok(())
}
None => Err(TryMsgError::new(msg))
}
}
}
impl<Msg: Message> SysTell for ActorRef<Msg> {
type Msg = Msg;
fn sys_tell(&self,
sys_msg: SystemMsg<Msg>,
sender: Option<ActorRef<Msg>>) {
let envelope = SystemEnvelope {
msg: sys_msg,
sender: sender
};
let _ = self.cell.send_sys_msg(envelope);
}
}
impl<Msg: Message> fmt::Debug for ActorRef<Msg> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Actor[{:?}]", self.uri)
}
}
impl<Msg: Message> fmt::Display for ActorRef<Msg> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Actor[{}://{}#{}]", self.uri.host, self.uri.path, self.uri.uid)
}
}
pub trait ActorRefFactory {
type Msg: Message;
fn actor_of(&self, props: BoxActorProd<Self::Msg>, name: &str) -> Result<ActorRef<Self::Msg>, CreateError>;
fn stop(&self, actor: &ActorRef<Self::Msg>);
}
pub trait TmpActorRefFactory {
type Msg: Message;
fn tmp_actor_of(&self, props: BoxActorProd<Self::Msg>) -> Result<ActorRef<Self::Msg>, CreateError>;
}
impl<Msg: Message> PartialEq for ActorRef<Msg> {
fn eq(&self, other: &ActorRef<Msg>) -> bool {
self.uri.path == other.uri.path
}
}