use crate::{
Actor, ActorControl, ActorRef, ActorWeak, BoxFuture, Message, Result, WeakActorControl,
};
use futures::FutureExt;
use std::fmt;
use std::time::Duration;
pub trait TellHandler<M: Send + 'static>: Send + Sync {
fn tell(&self, msg: M) -> BoxFuture<'_, Result<()>>;
fn tell_with_timeout(&self, msg: M, timeout: Duration) -> BoxFuture<'_, Result<()>>;
fn blocking_tell(&self, msg: M, timeout: Option<Duration>) -> Result<()>;
fn clone_boxed(&self) -> Box<dyn TellHandler<M>>;
fn downgrade(&self) -> Box<dyn WeakTellHandler<M>>;
fn as_control(&self) -> &dyn ActorControl;
fn debug_fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result;
}
pub trait AskHandler<M: Send + 'static, R: Send + 'static>: Send + Sync {
fn ask(&self, msg: M) -> BoxFuture<'_, Result<R>>;
fn ask_with_timeout(&self, msg: M, timeout: Duration) -> BoxFuture<'_, Result<R>>;
fn blocking_ask(&self, msg: M, timeout: Option<Duration>) -> Result<R>;
fn clone_boxed(&self) -> Box<dyn AskHandler<M, R>>;
fn downgrade(&self) -> Box<dyn WeakAskHandler<M, R>>;
fn as_control(&self) -> &dyn ActorControl;
fn debug_fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result;
}
pub trait WeakTellHandler<M: Send + 'static>: Send + Sync {
fn upgrade(&self) -> Option<Box<dyn TellHandler<M>>>;
fn clone_boxed(&self) -> Box<dyn WeakTellHandler<M>>;
fn as_weak_control(&self) -> &dyn WeakActorControl;
fn debug_fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result;
}
pub trait WeakAskHandler<M: Send + 'static, R: Send + 'static>: Send + Sync {
fn upgrade(&self) -> Option<Box<dyn AskHandler<M, R>>>;
fn clone_boxed(&self) -> Box<dyn WeakAskHandler<M, R>>;
fn as_weak_control(&self) -> &dyn WeakActorControl;
fn debug_fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result;
}
impl<M: Send + 'static> Clone for Box<dyn TellHandler<M>> {
fn clone(&self) -> Self {
self.clone_boxed()
}
}
impl<M: Send + 'static, R: Send + 'static> Clone for Box<dyn AskHandler<M, R>> {
fn clone(&self) -> Self {
self.clone_boxed()
}
}
impl<M: Send + 'static> fmt::Debug for Box<dyn TellHandler<M>> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.debug_fmt(f)
}
}
impl<M: Send + 'static, R: Send + 'static> fmt::Debug for Box<dyn AskHandler<M, R>> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.debug_fmt(f)
}
}
impl<M: Send + 'static> Clone for Box<dyn WeakTellHandler<M>> {
fn clone(&self) -> Self {
self.clone_boxed()
}
}
impl<M: Send + 'static, R: Send + 'static> Clone for Box<dyn WeakAskHandler<M, R>> {
fn clone(&self) -> Self {
self.clone_boxed()
}
}
impl<M: Send + 'static> fmt::Debug for Box<dyn WeakTellHandler<M>> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.debug_fmt(f)
}
}
impl<M: Send + 'static, R: Send + 'static> fmt::Debug for Box<dyn WeakAskHandler<M, R>> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.debug_fmt(f)
}
}
impl<T, M> TellHandler<M> for ActorRef<T>
where
T: Actor + Message<M> + 'static,
M: Send + 'static,
{
fn tell(&self, msg: M) -> BoxFuture<'_, Result<()>> {
ActorRef::tell(self, msg).boxed()
}
fn tell_with_timeout(&self, msg: M, timeout: Duration) -> BoxFuture<'_, Result<()>> {
ActorRef::tell_with_timeout(self, msg, timeout).boxed()
}
fn blocking_tell(&self, msg: M, timeout: Option<Duration>) -> Result<()> {
ActorRef::blocking_tell(self, msg, timeout)
}
fn clone_boxed(&self) -> Box<dyn TellHandler<M>> {
Box::new(self.clone())
}
fn downgrade(&self) -> Box<dyn WeakTellHandler<M>> {
Box::new(ActorRef::downgrade(self))
}
fn as_control(&self) -> &dyn ActorControl {
self
}
fn debug_fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("TellHandler")
.field("identity", &ActorRef::identity(self))
.field("alive", &ActorRef::is_alive(self))
.finish()
}
}
impl<T, M> AskHandler<M, <T as Message<M>>::Reply> for ActorRef<T>
where
T: Actor + Message<M> + 'static,
M: Send + 'static,
<T as Message<M>>::Reply: Send + 'static,
{
fn ask(&self, msg: M) -> BoxFuture<'_, Result<<T as Message<M>>::Reply>> {
ActorRef::ask(self, msg).boxed()
}
fn ask_with_timeout(
&self,
msg: M,
timeout: Duration,
) -> BoxFuture<'_, Result<<T as Message<M>>::Reply>> {
ActorRef::ask_with_timeout(self, msg, timeout).boxed()
}
fn blocking_ask(&self, msg: M, timeout: Option<Duration>) -> Result<<T as Message<M>>::Reply> {
ActorRef::blocking_ask(self, msg, timeout)
}
fn clone_boxed(&self) -> Box<dyn AskHandler<M, <T as Message<M>>::Reply>> {
Box::new(self.clone())
}
fn downgrade(&self) -> Box<dyn WeakAskHandler<M, <T as Message<M>>::Reply>> {
Box::new(ActorRef::downgrade(self))
}
fn as_control(&self) -> &dyn ActorControl {
self
}
fn debug_fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("AskHandler")
.field("identity", &ActorRef::identity(self))
.field("alive", &ActorRef::is_alive(self))
.finish()
}
}
impl<T, M> WeakTellHandler<M> for ActorWeak<T>
where
T: Actor + Message<M> + 'static,
M: Send + 'static,
{
fn upgrade(&self) -> Option<Box<dyn TellHandler<M>>> {
ActorWeak::upgrade(self).map(|r| Box::new(r) as Box<dyn TellHandler<M>>)
}
fn clone_boxed(&self) -> Box<dyn WeakTellHandler<M>> {
Box::new(self.clone())
}
fn as_weak_control(&self) -> &dyn WeakActorControl {
self
}
fn debug_fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("WeakTellHandler")
.field("identity", &ActorWeak::identity(self))
.field("alive", &ActorWeak::is_alive(self))
.finish()
}
}
impl<T, M> WeakAskHandler<M, <T as Message<M>>::Reply> for ActorWeak<T>
where
T: Actor + Message<M> + 'static,
M: Send + 'static,
<T as Message<M>>::Reply: Send + 'static,
{
fn upgrade(&self) -> Option<Box<dyn AskHandler<M, <T as Message<M>>::Reply>>> {
ActorWeak::upgrade(self)
.map(|r| Box::new(r) as Box<dyn AskHandler<M, <T as Message<M>>::Reply>>)
}
fn clone_boxed(&self) -> Box<dyn WeakAskHandler<M, <T as Message<M>>::Reply>> {
Box::new(self.clone())
}
fn as_weak_control(&self) -> &dyn WeakActorControl {
self
}
fn debug_fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("WeakAskHandler")
.field("identity", &ActorWeak::identity(self))
.field("alive", &ActorWeak::is_alive(self))
.finish()
}
}
impl<T, M> From<ActorRef<T>> for Box<dyn TellHandler<M>>
where
T: Actor + Message<M> + 'static,
M: Send + 'static,
{
fn from(actor_ref: ActorRef<T>) -> Self {
Box::new(actor_ref)
}
}
impl<T, M> From<&ActorRef<T>> for Box<dyn TellHandler<M>>
where
T: Actor + Message<M> + 'static,
M: Send + 'static,
{
fn from(actor_ref: &ActorRef<T>) -> Self {
Box::new(actor_ref.clone())
}
}
impl<T, M> From<ActorRef<T>> for Box<dyn AskHandler<M, <T as Message<M>>::Reply>>
where
T: Actor + Message<M> + 'static,
M: Send + 'static,
<T as Message<M>>::Reply: Send + 'static,
{
fn from(actor_ref: ActorRef<T>) -> Self {
Box::new(actor_ref)
}
}
impl<T, M> From<&ActorRef<T>> for Box<dyn AskHandler<M, <T as Message<M>>::Reply>>
where
T: Actor + Message<M> + 'static,
M: Send + 'static,
<T as Message<M>>::Reply: Send + 'static,
{
fn from(actor_ref: &ActorRef<T>) -> Self {
Box::new(actor_ref.clone())
}
}
impl<T, M> From<ActorWeak<T>> for Box<dyn WeakTellHandler<M>>
where
T: Actor + Message<M> + 'static,
M: Send + 'static,
{
fn from(actor_weak: ActorWeak<T>) -> Self {
Box::new(actor_weak)
}
}
impl<T, M> From<&ActorWeak<T>> for Box<dyn WeakTellHandler<M>>
where
T: Actor + Message<M> + 'static,
M: Send + 'static,
{
fn from(actor_weak: &ActorWeak<T>) -> Self {
Box::new(actor_weak.clone())
}
}
impl<T, M> From<ActorWeak<T>> for Box<dyn WeakAskHandler<M, <T as Message<M>>::Reply>>
where
T: Actor + Message<M> + 'static,
M: Send + 'static,
<T as Message<M>>::Reply: Send + 'static,
{
fn from(actor_weak: ActorWeak<T>) -> Self {
Box::new(actor_weak)
}
}
impl<T, M> From<&ActorWeak<T>> for Box<dyn WeakAskHandler<M, <T as Message<M>>::Reply>>
where
T: Actor + Message<M> + 'static,
M: Send + 'static,
<T as Message<M>>::Reply: Send + 'static,
{
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_handler_traits_are_send_sync() {
assert_send_sync::<Box<dyn TellHandler<()>>>();
assert_send_sync::<Box<dyn AskHandler<(), ()>>>();
assert_send_sync::<Box<dyn WeakTellHandler<()>>>();
assert_send_sync::<Box<dyn WeakAskHandler<(), ()>>>();
}
}