use crate::Stream; use pin_project_lite::pin_project; use std::pin::Pin; use std::task::{Context, Poll}; pin_project! { /// Stream returned by [`fuse()`][super::StreamExt::fuse]. #[derive(Debug)] pub struct Fuse { #[pin] stream: Option, } } impl Fuse where T: Stream, { pub(crate) fn new(stream: T) -> Fuse { Fuse { stream: Some(stream), } } } impl Stream for Fuse where T: Stream, { type Item = T::Item; fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let res = match Option::as_pin_mut(self.as_mut().project().stream) { Some(stream) => ready!(stream.poll_next(cx)), None => return Poll::Ready(None), }; if res.is_none() { // Do not poll the stream anymore self.as_mut().project().stream.set(None); } Poll::Ready(res) } fn size_hint(&self) -> (usize, Option) { match self.stream { Some(ref stream) => stream.size_hint(), None => (0, Some(0)), } } }