use futures_channel::oneshot;
use std::fmt;
use std::future::Future;
use std::pin::Pin;
use std::task::{Context, Poll};
pub struct JoinHandle<T> {
receiver: oneshot::Receiver<T>,
}
unsafe impl<T: Send> Send for JoinHandle<T> {}
unsafe impl<T: Send> Sync for JoinHandle<T> {}
impl<T> Unpin for JoinHandle<T> {}
impl<T> JoinHandle<T> {
pub(super) fn new(receiver: oneshot::Receiver<T>) -> JoinHandle<T> {
JoinHandle { receiver }
}
}
impl<T> Future for JoinHandle<T> {
type Output = Result<T, JoinError>;
fn poll(mut self: Pin<&mut Self>, context: &mut Context<'_>) -> Poll<Self::Output> {
if let Ok(received) = self.receiver.try_recv() {
if let Some(payload) = received {
Poll::Ready(Ok(payload))
} else {
let waker = context.waker().clone();
let wake_future = async move {
waker.wake();
};
wasm_bindgen_futures::spawn_local(wake_future);
Poll::Pending
}
} else {
Poll::Ready(Err(JoinError))
}
}
}
impl<T> fmt::Debug for JoinHandle<T>
where
T: fmt::Debug,
{
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_struct("JoinHandle").finish()
}
}
#[derive(Debug)]
pub struct JoinError;