dfir_pipes/pull/
filter.rs1use core::pin::Pin;
2
3use pin_project_lite::pin_project;
4
5use crate::pull::{FusedPull, Pull, PullStep};
6
7pin_project! {
8 #[must_use = "`Pull`s do nothing unless polled"]
10 #[derive(Clone, Debug)]
11 pub struct Filter<Prev, Func> {
12 #[pin]
13 prev: Prev,
14 func: Func,
15 }
16}
17
18impl<Prev, Func> Filter<Prev, Func>
19where
20 Self: Pull,
21{
22 pub(crate) const fn new(prev: Prev, func: Func) -> Self {
23 Self { prev, func }
24 }
25}
26
27impl<Prev, Func> Pull for Filter<Prev, Func>
28where
29 Prev: Pull,
30 Func: FnMut(&Prev::Item) -> bool,
31{
32 type Ctx<'ctx> = Prev::Ctx<'ctx>;
33
34 type Item = Prev::Item;
35 type Meta = Prev::Meta;
36 type CanPend = Prev::CanPend;
37 type CanEnd = Prev::CanEnd;
38
39 fn pull(
40 self: Pin<&mut Self>,
41 ctx: &mut Self::Ctx<'_>,
42 ) -> PullStep<Self::Item, Self::Meta, Self::CanPend, Self::CanEnd> {
43 let mut this = self.project();
44 loop {
45 return match this.prev.as_mut().pull(ctx) {
46 PullStep::Ready(item, meta) => {
47 if (this.func)(&item) {
48 PullStep::Ready(item, meta)
49 } else {
50 continue;
51 }
52 }
53 PullStep::Pending(can_pend) => PullStep::Pending(can_pend),
54 PullStep::Ended(can_end) => PullStep::Ended(can_end),
55 };
56 }
57 }
58
59 fn size_hint(&self) -> (usize, Option<usize>) {
60 let (_, upper) = self.prev.size_hint();
61 (0, upper)
62 }
63}
64
65impl<Prev, Func> FusedPull for Filter<Prev, Func>
66where
67 Prev: FusedPull,
68 Func: FnMut(&Prev::Item) -> bool,
69{
70}