git_editor/utils/
prompt.rs

1use crate::utils::types::Result;
2use colored::*;
3use std::io::{self, Write};
4
5pub fn prompt_for_input(prompt: &str) -> Result<String> {
6    print!("{prompt}: ");
7    io::stdout()
8        .flush()
9        .map_err(|e| format!("Failed to flush stdout: {e}"))?;
10
11    let mut input = String::new();
12    io::stdin()
13        .read_line(&mut input)
14        .map_err(|e| format!("Failed to read line: {e}"))?;
15
16    Ok(input.trim().to_string())
17}
18
19pub fn prompt_for_missing_arg(arg_name: &str) -> Result<String> {
20    let hint = format!(
21        "{} '{}'",
22        "Please provide a value for".yellow(),
23        arg_name.yellow().bold()
24    );
25    prompt_for_input(&hint)
26}
27
28// Prompts for input with a suggested default value shown in faded color. If the user presses Enter, the default is used. If they type something, that's used instead.
29pub fn prompt_with_default(prompt: &str, default_value: &str) -> Result<String> {
30    print!(
31        "{}: {} ",
32        prompt.yellow().bold(),
33        format!("({default_value})").bright_black()
34    );
35    io::stdout()
36        .flush()
37        .map_err(|e| format!("Failed to flush stdout: {e}"))?;
38
39    let mut input = String::new();
40    io::stdin()
41        .read_line(&mut input)
42        .map_err(|e| format!("Failed to read line: {e}"))?;
43
44    let input = input.trim();
45    if input.is_empty() {
46        Ok(default_value.to_string())
47    } else {
48        Ok(input.to_string())
49    }
50}
51
52#[cfg(test)]
53mod tests {
54    use super::*;
55
56    #[test]
57    fn test_prompt_for_missing_arg_formats_correctly() {
58        // We can't easily test interactive input, but we can test that the
59        // function formats the hint correctly
60        let arg_name = "test_arg";
61
62        // This would normally prompt for input, but we can test the format
63        // by checking that the function exists and takes the right parameters
64        assert_eq!(arg_name, "test_arg");
65    }
66
67    #[test]
68    fn test_prompt_functions_exist() {
69        // Test that both prompt functions exist and can be called
70        // (though we can't test interactive behavior in unit tests)
71
72        // These functions exist and have the right signatures
73        let _prompt_fn: fn(&str) -> Result<String> = prompt_for_input;
74        let _prompt_missing_fn: fn(&str) -> Result<String> = prompt_for_missing_arg;
75        let _prompt_with_default_fn: fn(&str, &str) -> Result<String> = prompt_with_default;
76    }
77}