sinktools/
try_for_each.rs

1//! [`TryForEach`] consuming sink.
2use core::pin::Pin;
3use core::task::{Context, Poll};
4
5use pin_project_lite::pin_project;
6
7use crate::Sink;
8
9pin_project! {
10    /// Same as [`crate::ForEach`] but the closure returns `Result<(), Error>` instead of `()`.
11    ///
12    /// This is useful when you want to handle errors in the closure.
13    ///
14    /// Synchronously consumes items and always returns `Poll::Ready(Ok(())`.
15    #[must_use = "sinks do nothing unless polled"]
16    pub struct TryForEach<Func> {
17        func: Func,
18    }
19}
20impl<Func> TryForEach<Func> {
21    /// Create with consuming `func`.
22    pub fn new<Item>(func: Func) -> Self
23    where
24        Self: Sink<Item>,
25    {
26        Self { func }
27    }
28}
29impl<Func, Item, Error> Sink<Item> for TryForEach<Func>
30where
31    Func: FnMut(Item) -> Result<(), Error>,
32{
33    type Error = Error;
34
35    fn poll_ready(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
36        Poll::Ready(Ok(()))
37    }
38
39    fn start_send(self: Pin<&mut Self>, item: Item) -> Result<(), Self::Error> {
40        (self.project().func)(item)
41    }
42
43    fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
44        Poll::Ready(Ok(()))
45    }
46
47    fn poll_close(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
48        Poll::Ready(Ok(()))
49    }
50}