Skip to main content

dfir_pipes/push/
for_each.rs

1//! [`ForEach`] terminal push combinator.
2use core::pin::Pin;
3
4use pin_project_lite::pin_project;
5
6use crate::No;
7use crate::push::{Push, PushStep};
8
9pin_project! {
10    /// Terminal push combinator that consumes each item with a closure.
11    ///
12    /// This is the push equivalent of the pull-side `ForEach` future.
13    /// It has no downstream push; items are consumed by `func`.
14    #[must_use = "`Push`es do nothing unless items are pushed into them"]
15    #[derive(Clone, Debug)]
16    pub struct ForEach<Func> {
17        func: Func,
18    }
19}
20
21impl<Func> ForEach<Func> {
22    /// Creates with consuming `func`.
23    pub(crate) const fn new<Item>(func: Func) -> Self
24    where
25        Func: FnMut(Item),
26    {
27        Self { func }
28    }
29}
30
31impl<Func, Item, Meta> Push<Item, Meta> for ForEach<Func>
32where
33    Func: FnMut(Item),
34    Meta: Copy,
35{
36    type Ctx<'ctx> = ();
37
38    type CanPend = No;
39
40    fn poll_ready(self: Pin<&mut Self>, _ctx: &mut Self::Ctx<'_>) -> PushStep<Self::CanPend> {
41        PushStep::Done
42    }
43
44    fn start_send(self: Pin<&mut Self>, item: Item, _meta: Meta) {
45        (self.project().func)(item);
46    }
47
48    fn poll_flush(self: Pin<&mut Self>, _ctx: &mut Self::Ctx<'_>) -> PushStep<Self::CanPend> {
49        PushStep::Done
50    }
51
52    fn size_hint(self: Pin<&mut Self>, _hint: (usize, Option<usize>)) {
53        // unused
54    }
55}