use crate::{Actor, ActorRef, ActorWeak, BoxFuture, Identity, Result};
use futures::FutureExt;
use std::fmt;
pub trait ActorControl: Send + Sync {
fn identity(&self) -> Identity;
fn is_alive(&self) -> bool;
fn stop(&self) -> BoxFuture<'_, Result<()>>;
fn kill(&self) -> Result<()>;
fn downgrade(&self) -> Box<dyn WeakActorControl>;
fn clone_boxed(&self) -> Box<dyn ActorControl>;
fn debug_fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result;
}
pub trait WeakActorControl: Send + Sync {
fn identity(&self) -> Identity;
fn is_alive(&self) -> bool;
fn upgrade(&self) -> Option<Box<dyn ActorControl>>;
fn clone_boxed(&self) -> Box<dyn WeakActorControl>;
fn debug_fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result;
}
impl Clone for Box<dyn ActorControl> {
fn clone(&self) -> Self {
self.clone_boxed()
}
}
impl Clone for Box<dyn WeakActorControl> {
fn clone(&self) -> Self {
self.clone_boxed()
}
}
impl fmt::Debug for Box<dyn ActorControl> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.debug_fmt(f)
}
}
impl fmt::Debug for Box<dyn WeakActorControl> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.debug_fmt(f)
}
}
impl<T: Actor + 'static> ActorControl for ActorRef<T> {
fn identity(&self) -> Identity {
ActorRef::identity(self)
}
fn is_alive(&self) -> bool {
ActorRef::is_alive(self)
}
fn stop(&self) -> BoxFuture<'_, Result<()>> {
ActorRef::stop(self).boxed()
}
fn kill(&self) -> Result<()> {
ActorRef::kill(self)
}
fn downgrade(&self) -> Box<dyn WeakActorControl> {
Box::new(ActorRef::downgrade(self))
}
fn clone_boxed(&self) -> Box<dyn ActorControl> {
Box::new(self.clone())
}
fn debug_fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("ActorControl")
.field("identity", &self.identity())
.field("alive", &self.is_alive())
.finish()
}
}
impl<T: Actor + 'static> WeakActorControl for ActorWeak<T> {
fn identity(&self) -> Identity {
ActorWeak::identity(self)
}
fn is_alive(&self) -> bool {
ActorWeak::is_alive(self)
}
fn upgrade(&self) -> Option<Box<dyn ActorControl>> {
ActorWeak::upgrade(self).map(|r| Box::new(r) as Box<dyn ActorControl>)
}
fn clone_boxed(&self) -> Box<dyn WeakActorControl> {
Box::new(self.clone())
}
fn debug_fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("WeakActorControl")
.field("identity", &self.identity())
.field("alive", &self.is_alive())
.finish()
}
}
impl<T: Actor + 'static> From<ActorRef<T>> for Box<dyn ActorControl> {
fn from(actor_ref: ActorRef<T>) -> Self {
Box::new(actor_ref)
}
}
impl<T: Actor + 'static> From<&ActorRef<T>> for Box<dyn ActorControl> {
fn from(actor_ref: &ActorRef<T>) -> Self {
Box::new(actor_ref.clone())
}
}
impl<T: Actor + 'static> From<ActorWeak<T>> for Box<dyn WeakActorControl> {
fn from(actor_weak: ActorWeak<T>) -> Self {
Box::new(actor_weak)
}
}
impl<T: Actor + 'static> From<&ActorWeak<T>> for Box<dyn WeakActorControl> {
fn from(actor_weak: &ActorWeak<T>) -> Self {
Box::new(actor_weak.clone())
}
}
#[cfg(test)]
mod tests {
use super::*;
fn assert_send_sync<T: Send + Sync>() {}
#[test]
fn test_actor_control_traits_are_send_sync() {
assert_send_sync::<Box<dyn ActorControl>>();
assert_send_sync::<Box<dyn WeakActorControl>>();
}
}