dfir_rs/compiled/pull/
zip_longest.rs

1use std::pin::Pin;
2use std::task::{Context, Poll, ready};
3
4use futures::stream::{FusedStream, Stream};
5use itertools::EitherOrBoth;
6use pin_project_lite::pin_project;
7
8pin_project! {
9    /// Special stream for the `zip_longest` operator.
10    #[must_use = "streams do nothing unless polled"]
11    pub struct ZipLongest<St1, St2> {
12        #[pin]
13        stream1: St1,
14        #[pin]
15        stream2: St2,
16    }
17}
18
19impl<St1, St2> ZipLongest<St1, St2>
20where
21    St1: FusedStream,
22    St2: FusedStream,
23{
24    /// Create a new `ZipLongest` stream from two source streams.
25    pub fn new(stream1: St1, stream2: St2) -> Self {
26        Self { stream1, stream2 }
27    }
28}
29
30impl<St1, St2> Stream for ZipLongest<St1, St2>
31where
32    St1: FusedStream,
33    St2: FusedStream,
34{
35    type Item = EitherOrBoth<St1::Item, St2::Item>;
36
37    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
38        let mut this = self.project();
39
40        let item_left = ready!(this.stream1.as_mut().poll_next(cx));
41        let item_right = ready!(this.stream2.as_mut().poll_next(cx));
42        Poll::Ready(match (item_left, item_right) {
43            (None, None) => None,
44            (Some(left), None) => Some(EitherOrBoth::Left(left)),
45            (None, Some(right)) => Some(EitherOrBoth::Right(right)),
46            (Some(left), Some(right)) => Some(EitherOrBoth::Both(left, right)),
47        })
48    }
49}