dope-fiber 0.8.0

The manifold runtime
Documentation
use core::future::Future;
use core::marker::PhantomData;
use core::pin::Pin;
use core::task::Poll;

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

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

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

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

    fn poll(self: Pin<&mut Self>, cx: &mut core::task::Context<'_>) -> Poll<Self::Output> {
        debug_assert!(
            core::ptr::eq(cx.waker().vtable(), &VTABLE),
            "fiber polled with a foreign waker"
        );
        let this = unsafe { self.get_unchecked_mut() };
        let mut fiber_cx = unsafe { Context::from_raw_task(cx.waker().data().cast_mut()) };
        let fiber_cx = unsafe { Pin::new_unchecked(&mut fiber_cx) };
        unsafe { Pin::new_unchecked(&mut this.fiber) }.poll(fiber_cx)
    }
}