BurntSushi/termcolor

Is `BufferWriter::print` expected to flush?

Open

#69 建立於 2023年2月23日

在 GitHub 查看
 (3 留言) (0 反應) (0 負責人)Rust (55 fork)github user discovery
enhancementhelp wanted

倉庫指標

Star
 (490 star)
PR 合併指標
 (30 天內沒有已合併 PR)

描述

(My triple is x86_64-unknown-linux-gnu and I'm using termcolor 1.2.0 with rustc 1.67.1)

In this example, I'm writing some text that is not postfixed by a newline to a Buffer and calling BufferWriter::print with it. I expect that this will flush the stream before reading from stdin, but it doesn't appear to.

use std::io::{self, BufRead, Write};
use termcolor::{BufferWriter, ColorChoice};
fn main() -> io::Result<()> {
    let stdout = BufferWriter::stdout(ColorChoice::Never);
    let mut buffer = stdout.buffer();
    buffer.write(b"text w/o newline")?;
    stdout.print(&buffer)?;
    io::stdin().lock().read_line(&mut String::new())?;
    Ok(())
}

It works as expected if I add a newline to the string literal (similar to std line buffering). And it's also the same if termcolor structures are swapped out for an std handle to the stream and a call to write_all.

The documentation for Buffer::print doesn't say anything about flushing or buffering, so the way I'm interpreting it is as a full unconditional write & flush of the buffer. If this is incorrect, I would also expect calling flush on the Buffer to fix this, but it doesn't appear to.

use std::io::{self, BufRead, Write};
use termcolor::{BufferWriter, ColorChoice};
fn main() -> io::Result<()> {
    let stdout = BufferWriter::stdout(ColorChoice::Never);
    let mut buffer = stdout.buffer();
    buffer.write(b"text w/o newline")?;
    stdout.print(&buffer)?;
    buffer.flush()?; // now we flush here, still the same
    io::stdin().lock().read_line(&mut String::new())?;
    Ok(())
}

Can you replicate this, and if so is this a bug? Thanks!

EDIT: I can flush streams manually but I don't know what state termcolor maintains that might be disrupted, and if that would be correct behavior on all platforms.

貢獻者指南