How to Read a Keypress from the Keyboard in Rust, similar to getch()

Kent West - kent.west@{that mail that swore to do no evil}

I struggled for days to figure out how to get a simple keypress from the keyboard. Finally! I found a crate on crates.io that makes it as simple as using "getch()" from the ncurses library.

The reason I did not use ncurses is because it requires an initialization step, which swaps out the screen for a new blank screen, which then disappears when you're finished with the curses mode.

I would have used the termion crate, but search high and low on the 'Net for a simple snippet of code that shows just the absolute bare minimum for getting a keypress, and you'll get a headache, and no solution, unless you're smarter than I am (granted, that's not a very high bar, but still...) I do not understand why coders will not give the simplest, barest-possible, COMMENTED!!!! code snippets so the newbie can get started. (Yes, I'm angry about this; Rust could be such a beautiful platform, if non-life-long-coders could learn how to code in it from simple examples and good explanations.)

Here's how to get a keypress from the keyboard in Rust:

Configure 'Cargo.toml'
$ cargo add getchar
src/main.rs
fn main() {
    let keypress = getchar::getchar().unwrap(); // getchar() returns an "Option<char>" type that must be unwrapped to get to the 'char' goody inside.

    println!("You pressed {}", keypress);
} // end of main()

And that's it. Simple.

Thanks to the author of getchar, Maks Rawski! And for those who want to see the entire code for this crate, you can see it on GitHub, or below. Yep, it's that simple. That's pretty much what I've been looking for, for days. (Comments would help, as I don't entirely understand it, but it's enough I think I could come to understand it if need be).

lib.rs
use std::io;
use std::io::{Read, Write};
use termion::raw::IntoRawMode;

pub enum Error{
    Exit,
    Unknown,
}

pub fn getchar() -> Result<u8, Error> {
    let mut buffer = [0];
    let stdout = io::stdout().into_raw_mode().unwrap();
    let mut stdin = io::stdin();

    stdout.lock().flush().unwrap();

    if stdin.read_exact(&mut buffer).is_ok() {
        if buffer[0] == 3 {
            Err(Error::Exit)
        } else {
            Ok(buffer[0])
        }
    } else {
        Err(Error::Unknown)
    }
}