Skip to main content

dope_fiber/abi/
pollfn.rs

1use core::{marker, pin, task};
2
3use crate::{abi, context};
4
5#[repr(transparent)]
6#[must_use = "a fiber does nothing unless it is driven"]
7#[derive(Debug)]
8pub struct PollFn<'d, F> {
9    f: F,
10    driver: marker::PhantomData<&'d mut &'d ()>,
11}
12
13impl<'d, F> Unpin for PollFn<'d, F> {}
14
15pub const fn poll_fn<'d, F, T>(mut f: F) -> impl abi::Fiber<'d, Output = T>
16where
17    F: FnMut(pin::Pin<&mut context::Context<'_, 'd>>) -> task::Poll<T>,
18{
19    PollFn::admitted(move |admit| f(admit.into_context()))
20}
21
22impl<'d, F> PollFn<'d, F> {
23    /// Retains the poll's initial admission for one child task or ready group.
24    pub const fn admitted<T>(f: F) -> Self
25    where
26        F: FnMut(context::Admission<'_, '_, 'd>) -> task::Poll<T>,
27    {
28        Self {
29            f,
30            driver: marker::PhantomData,
31        }
32    }
33}
34
35impl<'d, F, T> abi::Fiber<'d> for PollFn<'d, F>
36where
37    F: FnMut(context::Admission<'_, '_, 'd>) -> task::Poll<T>,
38{
39    type Output = T;
40
41    fn poll(call: context::PollCall<'_, '_, 'd, Self>) -> task::Poll<Self::Output> {
42        let (this, admit) = call.into_admit();
43        let this = this.get_mut();
44        (this.f)(admit)
45    }
46}