dfir_pipes/pull/
skip_while.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 SkipWhile<Prev, Func> {
12 #[pin]
13 prev: Prev,
14 func: Func,
15 skipping: bool,
16 }
17}
18
19impl<Prev, Func> SkipWhile<Prev, Func>
20where
21 Self: Pull,
22{
23 pub(crate) const fn new(prev: Prev, func: Func) -> Self {
24 Self {
25 prev,
26 func,
27 skipping: true,
28 }
29 }
30}
31
32impl<Prev, Func> Pull for SkipWhile<Prev, Func>
33where
34 Prev: Pull,
35 Func: FnMut(&Prev::Item) -> bool,
36{
37 type Ctx<'ctx> = Prev::Ctx<'ctx>;
38
39 type Item = Prev::Item;
40 type Meta = Prev::Meta;
41 type CanPend = Prev::CanPend;
42 type CanEnd = Prev::CanEnd;
43
44 fn pull(
45 self: Pin<&mut Self>,
46 ctx: &mut Self::Ctx<'_>,
47 ) -> PullStep<Self::Item, Self::Meta, Self::CanPend, Self::CanEnd> {
48 let mut this = self.project();
49
50 loop {
51 return match this.prev.as_mut().pull(ctx) {
52 PullStep::Ready(item, meta) => {
53 if *this.skipping && (this.func)(&item) {
54 continue;
55 }
56 *this.skipping = false;
57 PullStep::Ready(item, meta)
58 }
59 PullStep::Pending(can_pend) => PullStep::Pending(can_pend),
60 PullStep::Ended(can_end) => PullStep::Ended(can_end),
61 };
62 }
63 }
64
65 fn size_hint(&self) -> (usize, Option<usize>) {
66 let (_, upper) = self.prev.size_hint();
67 if self.skipping {
68 (0, upper)
70 } else {
71 self.prev.size_hint()
73 }
74 }
75}
76
77impl<Prev, Func> FusedPull for SkipWhile<Prev, Func>
78where
79 Prev: FusedPull,
80 Func: FnMut(&Prev::Item) -> bool,
81{
82}