unwrap_or_else includes a side-effect in a closure. This is a rare case where I'd feel OK with that. But ... the call to process::exit() terminates abruptly with no unwinding and doesn't call drop on anything. That can be problematic depending on what you've already done earlier in your binary. (see my "rant" here)
expect doesn't include the error message in the output but at least it panic!s so drop gets called.
most idiomatic, but not most common ;), would be playground
use std::io::{self, ErrorKind};
fn main() -> io::Result<()> {
let mut s = String::new();
io::stdin()
.read_line(&mut s)
.map_err(|err| std::io::Error::new(ErrorKind::InvalidInput, err))?;
Ok(())
}
(or use exit_safely for more control over the exit code[1])
You could and it would still be a decent option. That means you'd get a potentially less meaningful error message, as you'd not have the context that it was from trying to get input...
It's probably worth building the binary and briefly giving it something invalid to see whether you're happy with the resulting error message ...