Skip to main content

dope_fiber/task/done/
wait.rs

1use std::{marker, pin, task};
2
3use crate::{abi, context, wait};
4
5#[pin_project::pin_project]
6#[must_use = "a fiber does nothing unless it is driven"]
7pub struct Wait<'target, 'd, F, T> {
8    #[pin]
9    waiter: wait::Waiter<'target, 'd>,
10    f: F,
11    marker: marker::PhantomData<fn() -> T>,
12}
13
14impl<'target, 'd, F, T> Wait<'target, 'd, F, T>
15where
16    F: FnMut(
17        pin::Pin<&mut context::Context<'_, 'd>>,
18        pin::Pin<&wait::Waiter<'target, 'd>>,
19    ) -> task::Poll<T>,
20{
21    pub const fn new(f: F) -> Self {
22        use wait::Waiter;
23        Self {
24            waiter: Waiter::new(),
25            f,
26            marker: marker::PhantomData,
27        }
28    }
29}
30
31impl<'target, 'd, F, T> abi::Fiber<'d> for Wait<'target, 'd, F, T>
32where
33    F: FnMut(
34        pin::Pin<&mut context::Context<'_, 'd>>,
35        pin::Pin<&wait::Waiter<'target, 'd>>,
36    ) -> task::Poll<T>,
37{
38    type Output = T;
39
40    fn poll(call: context::PollCall<'_, '_, 'd, Self>) -> task::Poll<Self::Output> {
41        let (this, context) = call.into_parts();
42        let this = this.project();
43        let result = (this.f)(context, this.waiter.as_ref());
44        if result.is_ready() {
45            this.waiter.as_ref().unregister();
46        }
47        result
48    }
49}