I'm an absolute Rust beginner trying to build a simple confirmation function (yes or no), but I can't get the user to type anything, the function just keeps looping without waiting for user input:
""
""
""
etc.
is the result of the simplified version below.
use std::process;
use std::io;
pub fn confirm() {
loop {
let mut answer = String::new();
io::stdin().read_line(&mut answer)
.ok()
.expect("Failed to read line");
println!("{:?}", answer);
}
}
I've built my function around the guessing game example, and the rest of my program does nothing much, just reading a file and printing text.
Perhaps is due to the way my program (a git hook) is launched?
Assuming that the problem is that your git commit hook is running in an non-interactive environment, you can follow the advice laid out in that question and directly open /dev/tty
. Unlike STDIN, we don't treat it as a magical global variable and instead we pass it into the places we need:
use std::io::{self, BufRead, BufReader};
use std::fs::File;
type Tty = BufReader<File>;
fn open_tty() -> io::Result<Tty> {
let f = try!(File::open("/dev/tty"));
Ok(BufReader::new(f))
}
fn confirm(tty: &mut Tty) -> io::Result<String> {
let mut answer = String::new();
try!(tty.read_line(&mut answer));
Ok(answer)
}
fn inner_main() -> io::Result<()> {
let mut tty = try!(open_tty());
let answer = try!(confirm(&mut tty));
println!("The answer was: {}", answer);
Ok(())
}
fn main() {
inner_main().unwrap()
}
Note that this will not be platform independent. Specifically, this is very unlikely to work on Windows!
I've also gone ahead and allowed the io::Result
to propagate throughout the program, only panicking at the outermost shell.