Coverage Report

Created: 2025-07-11 06:53

/rust/registry/src/index.crates.io-6f17d22bba15001f/futures-util-0.3.31/src/io/lines.rs
Line
Count
Source (jump to first uncovered line)
1
use super::read_line::read_line_internal;
2
use futures_core::ready;
3
use futures_core::stream::Stream;
4
use futures_core::task::{Context, Poll};
5
use futures_io::AsyncBufRead;
6
use pin_project_lite::pin_project;
7
use std::io;
8
use std::mem;
9
use std::pin::Pin;
10
use std::string::String;
11
use std::vec::Vec;
12
13
pin_project! {
14
    /// Stream for the [`lines`](super::AsyncBufReadExt::lines) method.
15
    #[derive(Debug)]
16
    #[must_use = "streams do nothing unless polled"]
17
    pub struct Lines<R> {
18
        #[pin]
19
        reader: R,
20
        buf: String,
21
        bytes: Vec<u8>,
22
        read: usize,
23
    }
24
}
25
26
impl<R: AsyncBufRead> Lines<R> {
27
0
    pub(super) fn new(reader: R) -> Self {
28
0
        Self { reader, buf: String::new(), bytes: Vec::new(), read: 0 }
29
0
    }
30
}
31
32
impl<R: AsyncBufRead> Stream for Lines<R> {
33
    type Item = io::Result<String>;
34
35
0
    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
36
0
        let this = self.project();
37
0
        let n = ready!(read_line_internal(this.reader, cx, this.buf, this.bytes, this.read))?;
38
0
        *this.read = 0;
39
0
        if n == 0 && this.buf.is_empty() {
40
0
            return Poll::Ready(None);
41
0
        }
42
0
        if this.buf.ends_with('\n') {
43
0
            this.buf.pop();
44
0
            if this.buf.ends_with('\r') {
45
0
                this.buf.pop();
46
0
            }
47
0
        }
48
0
        Poll::Ready(Some(Ok(mem::take(this.buf))))
49
0
    }
50
}