pub struct AsyncLineReader<R: AsyncRead + Unpin> { /* private fields */ }Expand description
Buffered async line reader with line number tracking.
Reads input line-by-line asynchronously, automatically handling different line endings (LF, CRLF) and tracking the current line number for error reporting.
§Performance Characteristics
- Buffering: Configurable buffer size (default 64KB) for efficient I/O
- Zero-Copy: String allocations only for consumed lines
- Async: Non-blocking I/O suitable for high-concurrency scenarios
§When to Use Async vs Sync
Use Async When:
- Processing network streams or pipes
- High-concurrency scenarios (many parallel streams)
- Integration with async web servers or frameworks
- Need to process I/O without blocking threads
Use Sync When:
- Processing local files
- Single-threaded batch processing
- Simpler code without async complexity
- CPU-bound workloads with minimal I/O wait
§Examples
§Reading from Async Source
use hedl_stream::AsyncLineReader;
use tokio::fs::File;
let file = File::open("data.hedl").await?;
let mut reader = AsyncLineReader::new(file);
while let Some((line_num, line)) = reader.next_line().await? {
println!("{}: {}", line_num, line);
}§With Custom Buffer Size
use hedl_stream::AsyncLineReader;
use std::io::Cursor;
let input = "line1\nline2";
let reader = AsyncLineReader::with_capacity(Cursor::new(input), 256 * 1024);Implementations§
Source§impl<R: AsyncRead + Unpin> AsyncLineReader<R>
impl<R: AsyncRead + Unpin> AsyncLineReader<R>
Sourcepub fn new(reader: R) -> Self
pub fn new(reader: R) -> Self
Create a new async line reader with default buffer size (64KB) and max line length (1MB).
§Examples
use hedl_stream::AsyncLineReader;
use std::io::Cursor;
let input = "line1\nline2";
let reader = AsyncLineReader::new(Cursor::new(input));Sourcepub fn with_capacity(reader: R, capacity: usize) -> Self
pub fn with_capacity(reader: R, capacity: usize) -> Self
Create an async line reader with a specific buffer capacity and default max line length (1MB).
§Parameters
reader: The async readable sourcecapacity: Buffer size in bytes
§Examples
use hedl_stream::AsyncLineReader;
use std::io::Cursor;
// Use a larger buffer for large files
let reader = AsyncLineReader::with_capacity(
Cursor::new("data"),
256 * 1024 // 256KB
);Sourcepub fn with_max_length(reader: R, max_line_length: usize) -> Self
pub fn with_max_length(reader: R, max_line_length: usize) -> Self
Create with a specific max line length.
Sourcepub fn with_capacity_and_max_length(
reader: R,
capacity: usize,
max_line_length: usize,
) -> Self
pub fn with_capacity_and_max_length( reader: R, capacity: usize, max_line_length: usize, ) -> Self
Create with a specific buffer capacity and max line length.
Sourcepub fn line_number(&self) -> usize
pub fn line_number(&self) -> usize
Get the current line number.
Returns 0 before any lines are read, then increments with each line.
§Examples
use hedl_stream::AsyncLineReader;
use std::io::Cursor;
let mut reader = AsyncLineReader::new(Cursor::new("line1\nline2"));
assert_eq!(reader.line_number(), 0);
reader.next_line().await?;
assert_eq!(reader.line_number(), 1);
reader.next_line().await?;
assert_eq!(reader.line_number(), 2);Sourcepub async fn next_line(&mut self) -> StreamResult<Option<(usize, String)>>
pub async fn next_line(&mut self) -> StreamResult<Option<(usize, String)>>
Read the next line asynchronously.
Returns Ok(Some((line_num, line))) if a line was read, Ok(None) at EOF,
or Err on I/O errors.
Trailing newlines (LF or CRLF) are automatically stripped.
§Performance
This method awaits on I/O and yields to the runtime if data is not available, allowing other tasks to run. It does not block the thread.
§Examples
use hedl_stream::AsyncLineReader;
use std::io::Cursor;
let mut reader = AsyncLineReader::new(Cursor::new("hello\nworld"));
let (num, line) = reader.next_line().await?.unwrap();
assert_eq!(num, 1);
assert_eq!(line, "hello");
let (num, line) = reader.next_line().await?.unwrap();
assert_eq!(num, 2);
assert_eq!(line, "world");
assert_eq!(reader.next_line().await?, None);Sourcepub async fn peek_line(&mut self) -> StreamResult<Option<&(usize, String)>>
pub async fn peek_line(&mut self) -> StreamResult<Option<&(usize, String)>>
Peek at the next line without consuming it.
Returns a reference to the next line without advancing the reader.
Subsequent calls to peek_line() return the same line. Call next_line()
to consume it.
§Examples
use hedl_stream::AsyncLineReader;
use std::io::Cursor;
let mut reader = AsyncLineReader::new(Cursor::new("line1\nline2"));
// Peek multiple times
assert_eq!(reader.peek_line().await?, Some(&(1, "line1".to_string())));
assert_eq!(reader.peek_line().await?, Some(&(1, "line1".to_string())));
// Consume
reader.next_line().await?;
// Next peek is the second line
assert_eq!(reader.peek_line().await?, Some(&(2, "line2".to_string())));Sourcepub fn push_back(&mut self, line_num: usize, line: String)
pub fn push_back(&mut self, line_num: usize, line: String)
Push a line back to be read again.
The next call to next_line() or peek_line() will return this line.
Only one line can be pushed back at a time; subsequent calls overwrite
the previously pushed line.
§Examples
use hedl_stream::AsyncLineReader;
use std::io::Cursor;
let mut reader = AsyncLineReader::new(Cursor::new("line1\nline2"));
let line = reader.next_line().await?.unwrap();
assert_eq!(line, (1, "line1".to_string()));
// Push it back
reader.push_back(line.0, line.1);
// Read it again
let line = reader.next_line().await?.unwrap();
assert_eq!(line, (1, "line1".to_string()));