async-std
async-std copied to clipboard
Stdin read_line doesn't really read lines (when used like in the example)
When you write a simple consumer and feed it an entire file of multiple lines over stdin the behavior is not as expected:
fn main() {
async_std::task::block_on(async {
let mut line = String::new();
let stdin = async_std::io::stdin();
loop {
stdin.read_line(&mut line).await.unwrap();
println!("read({})", line);
}
});
}
this is
a multi line
file
Results in:
$ cargo run < test.txt | head -n 30
read(this is
)
read(this is
a multi line
)
read(this is
a multi line
)
read(this is
a multi line
file
)
read(this is
a multi line
file
)
read(this is
a multi line
file
)
read(this is
a multi line
file
)
read(this is
thread 'main' panicked at 'failed printing to stdout: Broken pipe (os error 32)', src/libstd/io/stdio.rs:805:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
I've found that this variant works correctly, but is not as the example suggests this API should be used. So it's either a documentation or an implementation bug:
fn main() {
async_std::task::block_on(async {
let stdin = async_std::io::stdin();
let mut buffer = String::new();
loop {
match stdin.read_line(&mut buffer).await {
Ok(0) => {
// EOF
break;
},
Ok(length) => {
let line = buffer.get(0..length).unwrap();
eprintln!("read({})", line);
buffer.replace_range(0..length, "");
},
Err(err) => {
eprintln!("Error reading from stdin: {}", err);
break;
}
}
}
});
}
This behaviour was seen with async-std 1.5.0 on both macOS and Arch Linux.