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:
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).
Back to TopThis alternative method uses a crate that has more features than the above getchar, most notably it works with things like the arrow keys, whereas getchar does not.
$ cargo add getch-rs
The keypress returned by the first example method above, getchar, returns the keypress in a "package" of an "Option<char>" type. This one, and the last one below, return their keypresses in a "Result" type. Both of these "package" types are like a delivery package from Amazon or UPS or FedEx, etc. The "Result" type, in particular, is like a delivery package with a big label on the outside that says either "Ok" or "Err". If it's an "Err", the contents won't be what you asked for, but rather an error message. If it's an "Ok", the contents will be what you asked for (hopefully). The ".unwrap()" unwraps the package, ignoring what the outer label says. You may wind up with a crashed program. Using ".expect()" instead of ".unwrap()" also opens the package, ignoring the outer label, but gives you the ability to add your own custom error message in the event of a program crash resulting from an error package. Ideally you'd properly handle the error situation, like we did here, but sometimes that's more trouble than it's worth.
We could unwrap() "g.getch" (g.getch().unwrap()
, like we did above using getchar and like we do below using termion. This example uses both methods, using the unwrap in the first section, and doing better error-handling in the second section. As mentioned in the previous paragraph, the third possibility is to use expect(), which is like unwrap, except it allows us to add our own custom message to an error condition.
The "whatever" above is just a variable name. Most often you'll see the variable name "c" (for "character") used.
Back to TopThis is essentially a sligtly different way of what the author of "getchar" did, as seen in the "lib.rs" code of that first example above. His is just more generic, returning the pressed key from a function, rather than getting the pressed key and doing something with it, all in one section of code.
Back to Top