hiasync 0.1.2

Supports only single-threaded asynchronous runtime
Documentation
use crate::{JoinHandle, JoinHandleInner};
use std::future::Future;
use std::pin::Pin;
use std::rc::{Rc, Weak};
use std::task::{Context, Poll};

pub(crate) trait Task {
    fn get_id(&self) -> u64;
    fn run(&mut self, ctx: &mut Context<'_>) -> Poll<()>;
}

pub(crate) struct TaskImpl<T: Future> {
    id: u64,
    future: T,
    handle: Weak<JoinHandleInner<T>>,
}

impl<T: Future + 'static> TaskImpl<T> {
    pub(crate) fn with_id(future: T, id: u64) -> (Box<dyn Task>, JoinHandle<T>) {
        let handle = JoinHandle::new();
        let task = Box::new(TaskImpl {
            id,
            future,
            handle: Rc::<JoinHandleInner<T>>::downgrade(handle.inner()),
        });
        (task, handle)
    }
}

impl<T: Future> Task for TaskImpl<T> {
    fn get_id(&self) -> u64 {
        self.id
    }
    fn run(&mut self, ctx: &mut Context<'_>) -> Poll<()> {
        let pin = unsafe { Pin::new_unchecked(&mut self.future) };
        match pin.poll(ctx) {
            Poll::Pending => Poll::Pending,
            Poll::Ready(output) => {
                if let Some(handle) = self.handle.upgrade() {
                    handle.set_output(output);
                }
                Poll::Ready(())
            }
        }
    }
}