Skip to main content

dope_fiber/abi/
map.rs

1use core::task;
2
3use crate::{abi, context};
4
5/// Maps the output of one fiber.
6#[pin_project::pin_project]
7#[must_use = "a fiber does nothing unless it is driven"]
8pub struct Map<F, M> {
9    #[pin]
10    fiber: F,
11    map: M,
12}
13
14impl<F, M> Map<F, M> {
15    pub const fn new(fiber: F, map: M) -> Self {
16        Self { fiber, map }
17    }
18}
19
20impl<'d, F, M, T> abi::Fiber<'d> for Map<F, M>
21where
22    F: abi::Fiber<'d>,
23    M: FnMut(F::Output) -> T,
24{
25    type Output = T;
26
27    fn poll(call: context::PollCall<'_, '_, 'd, Self>) -> task::Poll<T> {
28        let (this, context) = call.into_parts();
29        let this = this.project();
30        // SAFETY: this owner delegates its admission once; child Ready ends its polling authority.
31        unsafe { context::raw::Live::new(this.fiber).delegate(context) }.map(this.map)
32    }
33}