1 use crate::stream::Stream;
2 
3 use core::fmt;
4 use core::pin::Pin;
5 use core::task::{Context, Poll};
6 use pin_project_lite::pin_project;
7 
8 pin_project! {
9     /// Stream for the [`skip_while`](super::StreamExt::skip_while) method.
10     #[must_use = "streams do nothing unless polled"]
11     pub struct SkipWhile<St, F> {
12         #[pin]
13         stream: St,
14         predicate: Option<F>,
15     }
16 }
17 
18 impl<St, F> fmt::Debug for SkipWhile<St, F>
19 where
20     St: fmt::Debug,
21 {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result22     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
23         f.debug_struct("SkipWhile")
24             .field("stream", &self.stream)
25             .finish()
26     }
27 }
28 
29 impl<St, F> SkipWhile<St, F> {
new(stream: St, predicate: F) -> Self30     pub(super) fn new(stream: St, predicate: F) -> Self {
31         Self {
32             stream,
33             predicate: Some(predicate),
34         }
35     }
36 }
37 
38 impl<St, F> Stream for SkipWhile<St, F>
39 where
40     St: Stream,
41     F: FnMut(&St::Item) -> bool,
42 {
43     type Item = St::Item;
44 
poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>>45     fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
46         let mut this = self.project();
47         if let Some(predicate) = this.predicate {
48             loop {
49                 match ready!(this.stream.as_mut().poll_next(cx)) {
50                     Some(item) => {
51                         if !(predicate)(&item) {
52                             *this.predicate = None;
53                             return Poll::Ready(Some(item));
54                         }
55                     }
56                     None => return Poll::Ready(None),
57                 }
58             }
59         } else {
60             this.stream.poll_next(cx)
61         }
62     }
63 
size_hint(&self) -> (usize, Option<usize>)64     fn size_hint(&self) -> (usize, Option<usize>) {
65         let (lower, upper) = self.stream.size_hint();
66 
67         if self.predicate.is_some() {
68             return (0, upper);
69         }
70 
71         (lower, upper)
72     }
73 }
74