use std::{fmt, panic::Location, pin::Pin, task::Context, task::Poll, task::ready};
use crate::remote::RemoteJoin;
type Task<T> = crate::rt::task::Task<T>;
pub(crate) type SpawnLocation = &'static Location<'static>;
#[derive(Debug)]
pub struct JoinHandle<T> {
task: Task<T>,
}
impl<T> JoinHandle<T> {
pub(crate) fn new(task: Task<T>) -> Self {
JoinHandle { task }
}
pub fn cancel(self) {
self.task.cancel();
}
pub fn detach(self) {}
pub fn is_finished(&self) -> bool {
self.task.is_finished()
}
}
impl<T> Future for JoinHandle<T> {
type Output = Result<T, JoinError>;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
self.task.poll_join(cx).map(|out| out.ok_or(JoinError))
}
}
#[derive(Debug)]
pub struct RemoteJoinHandle<T> {
inner: Inner<T>,
}
#[derive(Debug)]
enum Inner<T> {
Local(JoinHandle<T>),
Remote(RemoteJoin<T>),
}
impl<T> RemoteJoinHandle<T> {
pub(crate) fn local(task: JoinHandle<T>) -> Self {
Self {
inner: Inner::Local(task),
}
}
pub(crate) fn remote(join: RemoteJoin<T>) -> Self {
Self {
inner: Inner::Remote(join),
}
}
pub fn cancel(self) {
match self.inner {
Inner::Local(t) => t.cancel(),
Inner::Remote(t) => t.cancel(),
}
}
pub fn detach(self) {}
pub fn is_finished(&self) -> bool {
match &self.inner {
Inner::Local(t) => t.is_finished(),
Inner::Remote(t) => t.is_finished(),
}
}
}
impl<T> Future for RemoteJoinHandle<T> {
type Output = Result<T, JoinError>;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
Poll::Ready(match &mut self.inner {
Inner::Local(t) => ready!(Pin::new(t).poll(cx)),
Inner::Remote(t) => ready!(t.poll_join(cx)).ok_or(JoinError),
})
}
}
#[derive(Debug, Copy, Clone)]
pub struct JoinError;
impl fmt::Display for JoinError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "JoinError")
}
}
impl std::error::Error for JoinError {}
#[cfg(all(test, not(feature = "tokio"), not(feature = "compio")))]
#[path = "../tests/unit/handle.rs"]
mod tests;