//! This shows how an application can write on stderr | |
//! instead of stdout, thus making it possible to | |
//! the command API instead of the "old style" direct | |
//! unbuffered API. | |
//! | |
//! This particular example is only suited to Unix | |
//! for now. | |
//! | |
//! cargo run --example stderr | |
use std::io::{stderr, Write}; | |
use crossterm::{ | |
cursor::{Hide, MoveTo, Show}, | |
event, | |
event::{Event, KeyCode, KeyEvent}, | |
execute, queue, | |
style::Print, | |
terminal::{self, EnterAlternateScreen, LeaveAlternateScreen}, | |
Result, | |
}; | |
const TEXT: &str = r#" | |
This screen is ran on stderr. | |
And when you hit enter, it prints on stdout. | |
This makes it possible to run an application and choose what will | |
be sent to any application calling yours. | |
For example, assuming you build this example with | |
cargo build --bin stderr | |
and then you run it with | |
cd "$(target/debug/stderr)" | |
what the application prints on stdout is used as argument to cd. | |
Try it out. | |
Hit any key to quit this screen: | |
1 will print `..` | |
2 will print `/` | |
3 will print `~` | |
Any other key will print this text (so that you may copy-paste) | |
"#; | |
fn run_app<W>(write: &mut W) -> Result<char> | |
where | |
W: Write, | |
{ | |
queue!( | |
write, | |
EnterAlternateScreen, // enter alternate screen | |
Hide // hide the cursor | |
)?; | |
let mut y = 1; | |
for line in TEXT.split('\n') { | |
queue!(write, MoveTo(1, y), Print(line.to_string()))?; | |
y += 1; | |
} | |
write.flush()?; | |
terminal::enable_raw_mode()?; | |
let user_char = read_char()?; // we wait for the user to hit a key | |
execute!(write, Show, LeaveAlternateScreen)?; // restore the cursor and leave the alternate screen | |
terminal::disable_raw_mode()?; | |
Ok(user_char) | |
} | |
pub fn read_char() -> Result<char> { | |
loop { | |
if let Event::Key(KeyEvent { | |
code: KeyCode::Char(c), | |
.. | |
}) = event::read()? | |
{ | |
return Ok(c); | |
} | |
} | |
} | |
// cargo run --example stderr | |
fn main() { | |
match run_app(&mut stderr()).unwrap() { | |
'1' => print!(".."), | |
'2' => print!("/"), | |
'3' => print!("~"), | |
_ => println!("{}", TEXT), | |
} | |
} |