use pin_project::pin_project;
use std::error::Error;
use std::future::Future;
use std::pin::Pin;
use std::task::{Context, Poll};
use crate::Canceled;
pub trait RuntimeJoinHandle:
Future<
Output = Result<
Result<<Self as RuntimeJoinHandle>::Output, Canceled>,
<Self as RuntimeJoinHandle>::Error,
>,
>
{
type Output: Send + 'static;
type Error: Error + Send + 'static;
}
#[pin_project]
pub struct JoinHandle<H> {
#[pin]
pub(crate) inner: H,
}
impl<T, H> Future for JoinHandle<H>
where
H: RuntimeJoinHandle<Output = T>,
T: Send + 'static,
{
type Output = Result<T, Box<dyn std::error::Error + Send + 'static>>;
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
match self.project().inner.poll(cx) {
Poll::Ready(Ok(Ok(v))) => Poll::Ready(Ok(v)),
Poll::Ready(Ok(Err(e))) => Poll::Ready(Err(Box::new(e))),
Poll::Ready(Err(e)) => Poll::Ready(Err(Box::new(e))),
Poll::Pending => Poll::Pending,
}
}
}