From 698f8c2f01ea549d77d7dc3338a12e04c11057b9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:02:58 +0200 Subject: Adding upstream version 1.64.0+dfsg1. Signed-off-by: Daniel Baumann --- .../futures-util/src/stream/try_stream/or_else.rs | 109 +++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 vendor/futures-util/src/stream/try_stream/or_else.rs (limited to 'vendor/futures-util/src/stream/try_stream/or_else.rs') diff --git a/vendor/futures-util/src/stream/try_stream/or_else.rs b/vendor/futures-util/src/stream/try_stream/or_else.rs new file mode 100644 index 000000000..cb69e8132 --- /dev/null +++ b/vendor/futures-util/src/stream/try_stream/or_else.rs @@ -0,0 +1,109 @@ +use core::fmt; +use core::pin::Pin; +use futures_core::future::TryFuture; +use futures_core::ready; +use futures_core::stream::{FusedStream, Stream, TryStream}; +use futures_core::task::{Context, Poll}; +#[cfg(feature = "sink")] +use futures_sink::Sink; +use pin_project_lite::pin_project; + +pin_project! { + /// Stream for the [`or_else`](super::TryStreamExt::or_else) method. + #[must_use = "streams do nothing unless polled"] + pub struct OrElse { + #[pin] + stream: St, + #[pin] + future: Option, + f: F, + } +} + +impl fmt::Debug for OrElse +where + St: fmt::Debug, + Fut: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("OrElse") + .field("stream", &self.stream) + .field("future", &self.future) + .finish() + } +} + +impl OrElse +where + St: TryStream, + F: FnMut(St::Error) -> Fut, + Fut: TryFuture, +{ + pub(super) fn new(stream: St, f: F) -> Self { + Self { stream, future: None, f } + } + + delegate_access_inner!(stream, St, ()); +} + +impl Stream for OrElse +where + St: TryStream, + F: FnMut(St::Error) -> Fut, + Fut: TryFuture, +{ + type Item = Result; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let mut this = self.project(); + + Poll::Ready(loop { + if let Some(fut) = this.future.as_mut().as_pin_mut() { + let item = ready!(fut.try_poll(cx)); + this.future.set(None); + break Some(item); + } else { + match ready!(this.stream.as_mut().try_poll_next(cx)) { + Some(Ok(item)) => break Some(Ok(item)), + Some(Err(e)) => { + this.future.set(Some((this.f)(e))); + } + None => break None, + } + } + }) + } + + fn size_hint(&self) -> (usize, Option) { + let future_len = if self.future.is_some() { 1 } else { 0 }; + let (lower, upper) = self.stream.size_hint(); + let lower = lower.saturating_add(future_len); + let upper = match upper { + Some(x) => x.checked_add(future_len), + None => None, + }; + (lower, upper) + } +} + +impl FusedStream for OrElse +where + St: TryStream + FusedStream, + F: FnMut(St::Error) -> Fut, + Fut: TryFuture, +{ + fn is_terminated(&self) -> bool { + self.future.is_none() && self.stream.is_terminated() + } +} + +// Forwarding impl of Sink from the underlying stream +#[cfg(feature = "sink")] +impl Sink for OrElse +where + S: Sink, +{ + type Error = S::Error; + + delegate_sink!(stream, Item); +} -- cgit v1.2.3