modcli/input/
input_builder.rs1use crate::output::hook;
2use rpassword::read_password;
3use std::io::{stdin, stdout, Write};
4
5pub fn prompt_text(prompt: &str, default: Option<&str>) -> String {
7 print!(
8 "{prompt}{} ",
9 default.map_or(String::new(), |d| format!(" [{d}]"))
10 );
11 if let Err(e) = stdout().flush() {
12 hook::warn(&format!("flush failed: {e}"));
13 }
14
15 let mut input = String::new();
16 if let Err(e) = stdin().read_line(&mut input) {
17 hook::error(&format!("failed to read input: {e}"));
18 return default.unwrap_or("").to_string();
19 }
20 let trimmed = input.trim();
21
22 if trimmed.is_empty() {
23 default.unwrap_or("").to_string()
24 } else {
25 trimmed.to_string()
26 }
27}
28
29pub fn confirm(prompt: &str, default_yes: bool) -> bool {
31 let yes_hint = if default_yes { "[Y/n]" } else { "[y/N]" };
32 print!("{prompt} {yes_hint} ");
33 if let Err(e) = stdout().flush() {
34 hook::warn(&format!("flush failed: {e}"));
35 }
36
37 let mut input = String::new();
38 if let Err(e) = stdin().read_line(&mut input) {
39 hook::error(&format!("failed to read input: {e}"));
40 return default_yes;
41 }
42 let trimmed = input.trim().to_lowercase();
43
44 match trimmed.as_str() {
45 "y" | "yes" => true,
46 "n" | "no" => false,
47 "" => default_yes,
48 _ => default_yes, }
50}
51
52pub fn prompt_password(prompt: &str) -> String {
54 print!("{prompt} ");
55 if let Err(e) = stdout().flush() {
56 hook::warn(&format!("flush failed: {e}"));
57 }
58 read_password().unwrap_or_default()
59}