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 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}