Skip to main content

x_bow/path_ext/
for_each.rs

1use std::{future::Future, pin::Pin, task::Poll};
2
3use futures_core::Stream;
4
5use crate::{until_change::UntilChange, Path, PathExt};
6
7/// A [Future]. See [for_each][crate::PathExt::for_each].
8pub struct ForEach<'a, P: Path + ?Sized, C: FnMut(&P::Out)> {
9    path: &'a P,
10    until_change: UntilChange<'a>,
11    closure: C,
12}
13
14impl<'a, P: Path + ?Sized, C: FnMut(&P::Out)> ForEach<'a, P, C> {
15    pub(super) fn new(path: &'a P, until_change: UntilChange<'a>, closure: C) -> Self {
16        Self {
17            path,
18            until_change,
19            closure,
20        }
21    }
22}
23
24impl<'a, P: Path + ?Sized, C: FnMut(&P::Out) + Unpin> Future for ForEach<'a, P, C> {
25    type Output = ();
26
27    fn poll(self: std::pin::Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> Poll<Self::Output> {
28        let this = self.get_mut();
29        let first = !this.until_change.has_been_polled();
30        if first | Pin::new(&mut this.until_change).poll_next(cx).is_ready() {
31            if let Some(data) = this.path.borrow_opt().as_deref() {
32                (this.closure)(data);
33            }
34        }
35        Poll::Pending
36    }
37}