BurntSushi/termcolor

Is `BufferWriter::print` expected to flush?

Open

#69 aperta il 23 feb 2023

Vedi su GitHub
 (3 commenti) (0 reazioni) (0 assegnatari)Rust (55 fork)github user discovery
enhancementhelp wanted

Metriche repository

Star
 (490 star)
Metriche merge PR
 (Nessuna PR mergiata in 30 g)

Descrizione

(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.

Guida contributor