use crate::Stream; use pin_project_lite::pin_project; use std::io; use std::pin::Pin; use std::task::{Context, Poll}; use tokio::io::{AsyncBufRead, Lines}; pin_project! { /// A wrapper around [`tokio::io::Lines`] that implements [`Stream`]. /// /// [`tokio::io::Lines`]: struct@tokio::io::Lines /// [`Stream`]: trait@crate::Stream #[derive(Debug)] #[cfg_attr(docsrs, doc(cfg(feature = "io-util")))] pub struct LinesStream { #[pin] inner: Lines, } } impl LinesStream { /// Create a new `LinesStream`. pub fn new(lines: Lines) -> Self { Self { inner: lines } } /// Get back the inner `Lines`. pub fn into_inner(self) -> Lines { self.inner } /// Obtain a pinned reference to the inner `Lines`. #[allow(clippy::wrong_self_convention)] // https://github.com/rust-lang/rust-clippy/issues/4546 pub fn as_pin_mut(self: Pin<&mut Self>) -> Pin<&mut Lines> { self.project().inner } } impl Stream for LinesStream { type Item = io::Result; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { self.project() .inner .poll_next_line(cx) .map(Result::transpose) } } impl AsRef> for LinesStream { fn as_ref(&self) -> &Lines { &self.inner } } impl AsMut> for LinesStream { fn as_mut(&mut self) -> &mut Lines { &mut self.inner } }