dope-fiber 0.8.0

The manifold runtime
Documentation
use core::future::Future;
use core::marker::PhantomData;
use core::mem::ManuallyDrop;
use core::pin::Pin;
use core::task::{Poll, RawWaker, Waker};

use super::waker::VTABLE;
use crate::{Context, Fiber};

#[repr(transparent)]
pub struct FutureFiber<'d, F> {
    future: F,
    marker: PhantomData<fn(&'d ()) -> &'d ()>,
}

impl<'d, F> FutureFiber<'d, F> {
    pub(super) const fn new(future: F) -> Self {
        Self {
            future,
            marker: PhantomData,
        }
    }
}

impl<'d, F> Fiber<'d> for FutureFiber<'d, F>
where
    F: Future,
{
    type Output = F::Output;

    fn poll(self: Pin<&mut Self>, mut cx: Pin<&mut Context<'_, 'd>>) -> Poll<Self::Output> {
        let this = unsafe { self.get_unchecked_mut() };
        let raw = RawWaker::new(cx.as_mut().raw_task().cast_const(), &VTABLE);
        let waker = ManuallyDrop::new(unsafe { Waker::from_raw(raw) });
        let mut future_cx = core::task::Context::from_waker(&waker);
        unsafe { Pin::new_unchecked(&mut this.future) }.poll(&mut future_cx)
    }
}