hiasync 0.1.1

Supports only single-threaded asynchronous runtime
Documentation
use crate::{LocalWaker, Waker};
use std::cell::RefCell;
use std::future::Future;
use std::pin::Pin;
use std::rc::Rc;
use std::task::{Context, Poll};

/// 获取异步任务的返回结果.
pub struct JoinHandle<T: Future> {
    inner: Rc<JoinHandleInner<T>>,
}

impl<T: Future> JoinHandle<T> {
    /// 异步任务是否结束
    pub fn is_finished(&self) -> bool {
        self.inner.output.borrow().is_some()
    }

    /// 获取结果,不会阻塞,如果未结束,返回None.
    /// 可先调用is_finished判断是否结束.
    pub fn join(self) -> Option<T::Output> {
        self.inner.output.take()
    }

    fn get(&self) -> Option<T::Output> {
        self.inner.output.take()
    }

    pub(crate) fn new() -> Self {
        Self {
            inner: Rc::new(JoinHandleInner::new()),
        }
    }

    pub(crate) fn inner(&self) -> &Rc<JoinHandleInner<T>> {
        &self.inner
    }
}

impl<T: Future> Future for JoinHandle<T> {
    type Output = T::Output;
    fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> {
        if let Some(output) = self.get() {
            return Poll::Ready(output);
        }
        self.inner
            .waker
            .replace(Some(LocalWaker::waker(ctx).clone()));
        Poll::Pending
    }
}

pub(crate) struct JoinHandleInner<T: Future> {
    //Waker don't support Send and Sync
    output: RefCell<Option<T::Output>>,
    waker: RefCell<Option<Waker>>,
}

impl<T: Future> JoinHandleInner<T> {
    fn new() -> Self {
        Self {
            output: RefCell::new(None),
            waker: RefCell::new(None),
        }
    }

    pub(crate) fn set_output(&self, val: T::Output) {
        self.output.replace(Some(val));
        if let Some(waker) = self.waker.take() {
            waker.wake();
        }
    }
}