uucore: add prompt_yes!() and read_yes()

These functions are based on existing functions and macros
in utils `cp`, `ln`, `mv ` and `rm`. This unifies the separate
implementations.
This commit is contained in:
Terts Diepraam 2022-11-16 15:11:44 +01:00
parent c00fc0a8c4
commit 6cdcfca573

View file

@ -166,6 +166,44 @@ pub fn args_os() -> impl Iterator<Item = OsString> {
ARGV.iter().cloned()
}
/// Read a line from stdin and check whether the first character is `'y'` or `'Y'`
pub fn read_yes() -> bool {
let mut s = String::new();
match std::io::stdin().read_line(&mut s) {
Ok(_) => matches!(s.chars().next(), Some('y' | 'Y')),
_ => false,
}
}
/// Prompt the user with a formatted string and returns `true` if they reply `'y'` or `'Y'`
///
/// This macro functions accepts the same syntax as `format!`. The prompt is written to
/// `stderr`. A space is also printed at the end for nice spacing between the prompt and
/// the user input. Any input starting with `'y'` or `'Y'` is interpreted as `yes`.
///
/// # Examples
/// ```
/// use uucore::prompt_yes;
/// let file = "foo.rs";
/// prompt_yes!("Do you want to delete '{}'?", file);
/// ```
/// will print something like below to `stderr` (with `util_name` substituted by the actual
/// util name) and will wait for user input.
/// ```txt
/// util_name: Do you want to delete 'foo.rs'?
/// ```
#[macro_export]
macro_rules! prompt_yes(
($($args:tt)+) => ({
use std::io::Write;
eprint!("{}: ", uucore::util_name());
eprint!($($args)+);
eprint!(" ");
uucore::crash_if_err!(1, std::io::stderr().flush());
uucore::read_yes()
})
);
#[cfg(test)]
mod tests {
use super::*;