use std::io::{self, Write};
use rpassword;
use tracing::info;
pub fn prompt_for_input(prompt: &str) -> Result<String, String> {
info!("{}", prompt);
io::stdout()
.flush()
.map_err(|e| format!("Failed to flush stdout: {}", e))?;
let mut input = String::new();
io::stdin()
.read_line(&mut input)
.map_err(|e| format!("Failed to read input: {}", e))?;
Ok(input.trim().to_string())
}
pub fn prompt_for_password(prompt: &str) -> Result<String, String> {
rpassword::prompt_password(prompt).map_err(|e| format!("Failed to read password: {}", e))
}
pub fn resolve_or_prompt(
provided: Option<String>,
stored: &mut Option<String>,
prompt: &str,
dirty: &mut bool,
) -> Result<String, String> {
if let Some(value) = provided {
if stored.as_ref() != Some(&value) {
*stored = Some(value.clone());
*dirty = true;
}
return Ok(value);
}
if let Some(value) = stored.clone() {
return Ok(value);
}
let value = prompt_for_input(prompt)?;
*stored = Some(value.clone());
*dirty = true;
Ok(value)
}
pub fn resolve_or_prompt_password(
provided: Option<String>,
stored: &mut Option<String>,
prompt: &str,
dirty: &mut bool,
) -> Result<String, String> {
if let Some(value) = provided {
if stored.as_ref() != Some(&value) {
*stored = Some(value.clone());
*dirty = true;
}
return Ok(value);
}
if let Some(value) = stored.clone() {
return Ok(value);
}
let value = prompt_for_password(prompt)?;
*stored = Some(value.clone());
*dirty = true;
Ok(value)
}