• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use crate::Stream;
2 use pin_project_lite::pin_project;
3 use std::io;
4 use std::pin::Pin;
5 use std::task::{Context, Poll};
6 use tokio::io::{AsyncBufRead, Lines};
7 
8 pin_project! {
9     /// A wrapper around [`tokio::io::Lines`] that implements [`Stream`].
10     ///
11     /// [`tokio::io::Lines`]: struct@tokio::io::Lines
12     /// [`Stream`]: trait@crate::Stream
13     #[derive(Debug)]
14     #[cfg_attr(docsrs, doc(cfg(feature = "io-util")))]
15     pub struct LinesStream<R> {
16         #[pin]
17         inner: Lines<R>,
18     }
19 }
20 
21 impl<R> LinesStream<R> {
22     /// Create a new `LinesStream`.
new(lines: Lines<R>) -> Self23     pub fn new(lines: Lines<R>) -> Self {
24         Self { inner: lines }
25     }
26 
27     /// Get back the inner `Lines`.
into_inner(self) -> Lines<R>28     pub fn into_inner(self) -> Lines<R> {
29         self.inner
30     }
31 
32     /// Obtain a pinned reference to the inner `Lines<R>`.
33     #[allow(clippy::wrong_self_convention)] // https://github.com/rust-lang/rust-clippy/issues/4546
as_pin_mut(self: Pin<&mut Self>) -> Pin<&mut Lines<R>>34     pub fn as_pin_mut(self: Pin<&mut Self>) -> Pin<&mut Lines<R>> {
35         self.project().inner
36     }
37 }
38 
39 impl<R: AsyncBufRead> Stream for LinesStream<R> {
40     type Item = io::Result<String>;
41 
poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>>42     fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
43         self.project()
44             .inner
45             .poll_next_line(cx)
46             .map(Result::transpose)
47     }
48 }
49 
50 impl<R> AsRef<Lines<R>> for LinesStream<R> {
as_ref(&self) -> &Lines<R>51     fn as_ref(&self) -> &Lines<R> {
52         &self.inner
53     }
54 }
55 
56 impl<R> AsMut<Lines<R>> for LinesStream<R> {
as_mut(&mut self) -> &mut Lines<R>57     fn as_mut(&mut self) -> &mut Lines<R> {
58         &mut self.inner
59     }
60 }
61