dfir_rs/compiled/pull/
zip_longest.rs1use 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 #[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 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}