2018-10-31 07:18:57 +00:00
|
|
|
use std::io::{self, BufRead, Write};
|
2017-07-27 09:24:43 +00:00
|
|
|
|
|
|
|
use url::Url;
|
|
|
|
|
|
|
|
use errors::Result;
|
|
|
|
|
|
|
|
/// Wait for user input and return what they typed
|
|
|
|
fn read_line() -> Result<String> {
|
|
|
|
let stdin = io::stdin();
|
|
|
|
let stdin = stdin.lock();
|
|
|
|
let mut lines = stdin.lines();
|
|
|
|
lines
|
|
|
|
.next()
|
|
|
|
.and_then(|l| l.ok())
|
2017-08-31 09:01:26 +00:00
|
|
|
.ok_or_else(|| "unable to read from stdin for confirmation".into())
|
2017-07-27 09:24:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Ask a yes/no question to the user
|
|
|
|
pub fn ask_bool(question: &str, default: bool) -> Result<bool> {
|
|
|
|
print!("{} {}: ", question, if default { "[Y/n]" } else { "[y/N]" });
|
|
|
|
let _ = io::stdout().flush();
|
|
|
|
let input = read_line()?;
|
|
|
|
|
|
|
|
match &*input {
|
|
|
|
"y" | "Y" | "yes" | "YES" | "true" => Ok(true),
|
|
|
|
"n" | "N" | "no" | "NO" | "false" => Ok(false),
|
|
|
|
"" => Ok(default),
|
|
|
|
_ => {
|
|
|
|
println!("Invalid choice: '{}'", input);
|
|
|
|
ask_bool(question, default)
|
2018-10-31 07:18:57 +00:00
|
|
|
}
|
2017-07-27 09:24:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Ask a question to the user where they can write a URL
|
|
|
|
pub fn ask_url(question: &str, default: &str) -> Result<String> {
|
|
|
|
print!("{} ({}): ", question, default);
|
|
|
|
let _ = io::stdout().flush();
|
|
|
|
let input = read_line()?;
|
|
|
|
|
|
|
|
match &*input {
|
|
|
|
"" => Ok(default.to_string()),
|
2018-10-31 07:18:57 +00:00
|
|
|
_ => match Url::parse(&input) {
|
|
|
|
Ok(_) => Ok(input),
|
|
|
|
Err(_) => {
|
|
|
|
println!("Invalid URL: '{}'", input);
|
|
|
|
ask_url(question, default)
|
2017-07-27 09:24:43 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|