Search code examples
rustconsole

How do I overwrite console output?


Is there a way to overwrite console output using Rust instead of simply appending?

An example would be printing progress as a percentage; I would rather overwrite the line than print a new line.


Solution

  • Consoles are usually controlled by printing out "control characters", but what they are depends on the platform and terminal type. You probably don't want to reinvent the wheel to do this.

    You can use the crossterm crate to get this kind of console control. A simple example is:

    use std::{thread, time};
    use std::io::{Write, stdout};
    use crossterm::{QueueableCommand, cursor, terminal, ExecutableCommand};
    
    fn main() {
        let mut stdout = stdout();
    
        stdout.execute(cursor::Hide).unwrap();
        for i in (1..30).rev() {
            stdout.queue(cursor::SavePosition).unwrap();
            stdout.write_all(format!("{}: FOOBAR ", i).as_bytes()).unwrap();
            stdout.queue(cursor::RestorePosition).unwrap();
            stdout.flush().unwrap();
            thread::sleep(time::Duration::from_millis(100));
    
            stdout.queue(cursor::RestorePosition).unwrap();
            stdout.queue(terminal::Clear(terminal::ClearType::FromCursorDown)).unwrap();
        }
        stdout.execute(cursor::Show).unwrap();
    
        println!("Done!");
    }