dfir_pipes/push/
filter_map.rs1use core::pin::Pin;
3
4use pin_project_lite::pin_project;
5
6use crate::push::{Push, PushStep};
7
8pin_project! {
9 #[must_use = "`Push`es do nothing unless items are pushed into them"]
11 #[derive(Clone, Debug)]
12 pub struct FilterMap<Next, Func> {
13 #[pin]
14 next: Next,
15 func: Func,
16 }
17}
18
19impl<Next, Func> FilterMap<Next, Func> {
20 pub(crate) const fn new<In, Out>(func: Func, next: Next) -> Self
22 where
23 Func: FnMut(In) -> Option<Out>,
24 {
25 Self { next, func }
26 }
27}
28
29impl<Next, Func, In, Out, Meta> Push<In, Meta> for FilterMap<Next, Func>
30where
31 Next: Push<Out, Meta>,
32 Func: FnMut(In) -> Option<Out>,
33 Meta: Copy,
34{
35 type Ctx<'ctx> = Next::Ctx<'ctx>;
36
37 type CanPend = Next::CanPend;
38
39 fn poll_ready(self: Pin<&mut Self>, ctx: &mut Self::Ctx<'_>) -> PushStep<Self::CanPend> {
40 self.project().next.poll_ready(ctx)
41 }
42
43 fn start_send(self: Pin<&mut Self>, item: In, meta: Meta) {
44 let this = self.project();
45 if let Some(item) = (this.func)(item) {
46 this.next.start_send(item, meta)
47 }
48 }
49
50 fn poll_flush(self: Pin<&mut Self>, ctx: &mut Self::Ctx<'_>) -> PushStep<Self::CanPend> {
51 self.project().next.poll_flush(ctx)
52 }
53
54 fn size_hint(self: Pin<&mut Self>, hint: (usize, Option<usize>)) {
55 self.project().next.size_hint((0, hint.1));
56 }
57}