use std::{
future::Future,
marker::PhantomData,
ops::{Deref, DerefMut},
pin::Pin,
task::{Context, Poll},
time::Duration,
};
pub use map::Map;
use pin_project_lite::pin_project;
pub use then::Then;
pub use timeout::Timeout;
use crate::actor::Actor;
mod either;
mod map;
pub mod result;
mod then;
mod timeout;
pub trait ActorFuture<A: Actor> {
type Output;
fn poll(
self: Pin<&mut Self>,
srv: &mut A,
ctx: &mut A::Context,
task: &mut Context<'_>,
) -> Poll<Self::Output>;
}
pub trait ActorFutureExt<A: Actor>: ActorFuture<A> {
fn map<F, U>(self, f: F) -> Map<Self, F>
where
F: FnOnce(Self::Output, &mut A, &mut A::Context) -> U,
Self: Sized,
{
Map::new(self, f)
}
fn then<F, Fut>(self, f: F) -> Then<Self, Fut, F>
where
F: FnOnce(Self::Output, &mut A, &mut A::Context) -> Fut,
Fut: ActorFuture<A>,
Self: Sized,
{
then::new(self, f)
}
fn timeout(self, timeout: Duration) -> Timeout<Self>
where
Self: Sized,
{
Timeout::new(self, timeout)
}
fn boxed_local(self) -> LocalBoxActorFuture<A, Self::Output>
where
Self: Sized + 'static,
{
Box::pin(self)
}
}
impl<F, A> ActorFutureExt<A> for F
where
F: ActorFuture<A>,
A: Actor,
{
}
pub type LocalBoxActorFuture<A, I> = Pin<Box<dyn ActorFuture<A, Output = I>>>;
impl<F, A> ActorFuture<A> for Box<F>
where
F: ActorFuture<A> + Unpin + ?Sized,
A: Actor,
{
type Output = F::Output;
fn poll(
mut self: Pin<&mut Self>,
srv: &mut A,
ctx: &mut A::Context,
task: &mut Context<'_>,
) -> Poll<Self::Output> {
Pin::new(&mut **self.as_mut()).poll(srv, ctx, task)
}
}
impl<P, A> ActorFuture<A> for Pin<P>
where
P: Unpin + DerefMut,
<P as Deref>::Target: ActorFuture<A>,
A: Actor,
{
type Output = <<P as Deref>::Target as ActorFuture<A>>::Output;
fn poll(
self: Pin<&mut Self>,
srv: &mut A,
ctx: &mut A::Context,
task: &mut Context<'_>,
) -> Poll<Self::Output> {
Pin::get_mut(self).as_mut().poll(srv, ctx, task)
}
}
pub trait WrapFuture<A>
where
A: Actor,
{
type Future: ActorFuture<A>;
#[deprecated(since = "0.11.0", note = "Please use WrapFuture::into_actor")]
#[doc(hidden)]
fn actfuture(self) -> Self::Future;
fn into_actor(self, a: &A) -> Self::Future;
}
impl<F: Future, A: Actor> WrapFuture<A> for F {
type Future = FutureWrap<F, A>;
#[doc(hidden)]
fn actfuture(self) -> Self::Future {
wrap_future(self)
}
fn into_actor(self, _: &A) -> Self::Future {
wrap_future(self)
}
}
pin_project! {
pub struct FutureWrap<F, A>
where
F: Future,
A: Actor,
{
#[pin]
fut: F,
_act: PhantomData<A>
}
}
pub fn wrap_future<F, A>(f: F) -> FutureWrap<F, A>
where
F: Future,
A: Actor,
{
FutureWrap {
fut: f,
_act: PhantomData,
}
}
impl<F, A> ActorFuture<A> for FutureWrap<F, A>
where
F: Future,
A: Actor,
{
type Output = F::Output;
fn poll(
self: Pin<&mut Self>,
_: &mut A,
_: &mut A::Context,
task: &mut Context<'_>,
) -> Poll<Self::Output> {
self.project().fut.poll(task)
}
}