use crate::all::*;
use futures::{future::BoxFuture, Future};
use std::{any::TypeId, sync::Arc};
pub trait ActorRef: Sized {
type ActorType: ActorType;
fn channel_ref(actor_ref: &Self) -> &Arc<<Self::ActorType as ActorType>::Channel>;
}
pub trait ActorRefExt: ActorRef {
fn envelope<M>(&self, msg: M) -> Envelope<'_, Self::ActorType, M>
where
M: Message,
Self::ActorType: Accepts<M>,
{
Envelope::new(Self::channel_ref(self), msg)
}
fn clone_address(&self) -> Address<Self::ActorType> {
let channel = Self::channel_ref(self).clone();
channel.increment_address_count();
Address::from_channel(channel)
}
fn close(&self) -> bool {
Self::channel_ref(self).close()
}
fn halt_some(&self, n: u32) {
Self::channel_ref(self).halt_some(n)
}
fn halt(&self) {
Self::channel_ref(self).halt()
}
fn process_count(&self) -> usize {
Self::channel_ref(self).process_count()
}
fn msg_count(&self) -> usize {
Self::channel_ref(self).msg_count()
}
fn address_count(&self) -> usize {
Self::channel_ref(self).address_count()
}
fn is_closed(&self) -> bool {
Self::channel_ref(self).is_closed()
}
fn capacity(&self) -> Capacity {
Self::channel_ref(self).capacity()
}
fn has_exited(&self) -> bool {
Self::channel_ref(self).has_exited()
}
fn actor_id(&self) -> ActorId {
Self::channel_ref(self).actor_id()
}
fn try_send<M>(&self, msg: M) -> Result<M::Returned, TrySendError<M>>
where
M: Message,
Self::ActorType: Accepts<M>,
{
<Self::ActorType as Accepts<M>>::try_send(Self::channel_ref(self), msg)
}
fn force_send<M>(&self, msg: M) -> Result<M::Returned, TrySendError<M>>
where
M: Message,
Self::ActorType: Accepts<M>,
{
<Self::ActorType as Accepts<M>>::force_send(Self::channel_ref(self), msg)
}
fn send_blocking<M>(&self, msg: M) -> Result<M::Returned, SendError<M>>
where
M: Message,
Self::ActorType: Accepts<M>,
{
<Self::ActorType as Accepts<M>>::send_blocking(Self::channel_ref(self), msg)
}
fn send<M>(&self, msg: M) -> <Self::ActorType as Accepts<M>>::SendFut<'_>
where
M: Message,
Self::ActorType: Accepts<M>,
{
<Self::ActorType as Accepts<M>>::send(Self::channel_ref(self), msg)
}
fn try_request<M, F, E, R>(&self, msg: M) -> BoxFuture<'_, Result<R, TryRequestError<M, E>>>
where
M: Message<Returned = F> + Send + 'static,
F: Future<Output = Result<R, E>> + Send,
Self::ActorType: Accepts<M>,
{
<Self::ActorType as AcceptsExt<M>>::try_request(Self::channel_ref(self), msg)
}
fn force_request<M, F, E, R>(&self, msg: M) -> BoxFuture<'_, Result<R, TryRequestError<M, E>>>
where
M: Message<Returned = F> + Send + 'static,
F: Future<Output = Result<R, E>> + Send,
Self::ActorType: Accepts<M>,
{
<Self::ActorType as AcceptsExt<M>>::force_request(Self::channel_ref(self), msg)
}
fn request<M, F, E, R>(&self, msg: M) -> BoxFuture<'_, Result<R, RequestError<M, E>>>
where
M: Message<Returned = F> + Send + 'static,
F: Future<Output = Result<R, E>> + Send,
Self::ActorType: Accepts<M>,
{
<Self::ActorType as AcceptsExt<M>>::request(Self::channel_ref(self), msg)
}
fn try_send_checked<M>(&self, msg: M) -> Result<M::Returned, TrySendCheckedError<M>>
where
M: Message + Send + 'static,
M::Payload: Send + 'static,
Self::ActorType: DynActorType,
{
<Self as ActorRef>::channel_ref(self).try_send_checked(msg)
}
fn force_send_checked<M>(&self, msg: M) -> Result<M::Returned, TrySendCheckedError<M>>
where
M: Message + Send + 'static,
M::Payload: Send + 'static,
Self::ActorType: DynActorType,
{
<Self as ActorRef>::channel_ref(self).force_send_checked(msg)
}
fn send_blocking_checked<M>(&self, msg: M) -> Result<M::Returned, SendCheckedError<M>>
where
M: Message + Send + 'static,
M::Payload: Send + 'static,
Self::ActorType: DynActorType,
{
<Self as ActorRef>::channel_ref(self).send_blocking_checked(msg)
}
fn send_checked<M>(&self, msg: M) -> BoxFuture<'_, Result<M::Returned, SendCheckedError<M>>>
where
M::Returned: Send,
M: Message + Send + 'static,
M::Payload: Send + 'static,
Self::ActorType: DynActorType,
{
<Self as ActorRef>::channel_ref(self).send_checked(msg)
}
fn accepts(&self, id: &TypeId) -> bool {
<Self as ActorRef>::channel_ref(self).accepts(id)
}
}
impl<T> ActorRefExt for T where T: ActorRef {}
pub trait Transformable: ActorRef {
type IntoRef<T>: Transformable<ActorType = T>
where
T: ActorType;
fn transform_unchecked_into<T>(self) -> Self::IntoRef<T>
where
T: DynActorType;
fn transform_into<T>(self) -> Self::IntoRef<T>
where
Self::ActorType: TransformInto<T>,
T: ActorType;
fn downcast<T>(self) -> Result<Self::IntoRef<T>, Self>
where
Self::ActorType: DynActorType,
T: ActorType,
T::Channel: Sized + 'static;
fn try_transform_into<T>(self) -> Result<Self::IntoRef<T>, Self>
where
Self::ActorType: DynActorType,
T: DynActorType,
{
if T::msg_ids().iter().all(|id| self.accepts(id)) {
Ok(self.transform_unchecked_into())
} else {
Err(self)
}
}
fn into_dyn(self) -> Self::IntoRef<DynActor!()> {
self.transform_unchecked_into()
}
}