use std::future::Future;
use std::pin::Pin;
use std::task::{Context, Poll};
use futures_util::FutureExt;
use crate::address::{ActorJoinHandle, Address};
use crate::chan::RefCounter;
pub fn scoped<A, Rc, F, R>(address: &Address<A, Rc>, task: F) -> ScopedTask<F>
where
Rc: RefCounter,
F: Future<Output = R>,
{
ScopedTask {
join_handle: address.join(),
fut: task,
}
}
pin_project_lite::pin_project! {
#[must_use = "Futures do nothing unless polled"]
pub struct ScopedTask<F: ?Sized> {
join_handle: ActorJoinHandle,
#[pin]
fut: F,
}
}
impl<F> Future for ScopedTask<F>
where
F: Future,
{
type Output = Option<F::Output>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = self.project();
match this.join_handle.poll_unpin(cx) {
Poll::Ready(()) => Poll::Ready(None),
Poll::Pending => match this.fut.poll(cx) {
Poll::Ready(v) => Poll::Ready(Some(v)),
Poll::Pending => Poll::Pending,
},
}
}
}