mi6_cli/display/
prompt.rs

1//! User prompt utilities for interactive CLI confirmation.
2
3use anyhow::{Context, Result};
4use std::io::{BufRead, Write};
5
6/// Ask the user for confirmation, prompting on stderr.
7///
8/// Use this for destructive operations where the prompt shouldn't
9/// be captured in piped stdout output.
10pub fn confirm(prompt: &str) -> Result<bool> {
11    eprint!("{} [y/N] ", prompt);
12    std::io::stderr()
13        .flush()
14        .context("failed to flush stderr")?;
15
16    let stdin = std::io::stdin();
17    let mut line = String::new();
18    stdin
19        .lock()
20        .read_line(&mut line)
21        .context("failed to read input")?;
22
23    let answer = line.trim().to_lowercase();
24    Ok(answer == "y" || answer == "yes")
25}
26
27/// Ask the user for confirmation, prompting on stdout.
28///
29/// Use this for standard interactive prompts where capturing
30/// the prompt in piped output is acceptable.
31pub fn confirm_stdout(prompt: &str) -> Result<bool> {
32    print!("{} [y/N] ", prompt);
33    std::io::stdout()
34        .flush()
35        .context("failed to flush stdout")?;
36
37    let stdin = std::io::stdin();
38    let mut line = String::new();
39    stdin
40        .lock()
41        .read_line(&mut line)
42        .context("failed to read input")?;
43
44    let answer = line.trim().to_lowercase();
45    Ok(answer == "y" || answer == "yes")
46}
47
48#[cfg(test)]
49mod tests {
50    // Note: Interactive prompt tests require manual testing
51    // as they read from stdin which cannot be easily mocked in unit tests.
52}