use std::fmt;
use std::io::{self, Write};
use std::path::Path;
#[must_use]
pub fn ask_confirmation_with_prompt(prompt: &str) -> bool {
print!("{prompt} (y/N) ");
_ = io::stdout().flush();
let mut answer = String::new();
if io::stdin().read_line(&mut answer).is_err() {
eprintln!("Error reading user input.");
return false;
}
matches!(answer.to_ascii_lowercase().trim(), "y" | "yes")
}
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub enum Action {
Sync,
RSync,
Link,
Clean,
}
impl fmt::Display for Action {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Sync => write!(f, "Synced"),
Self::RSync => write!(f, "rSynced"),
Self::Link => write!(f, "Linked"),
Self::Clean => write!(f, "Removed"),
}
}
}
pub fn print_files(files: &[String]) {
let mut stdout = io::stdout().lock();
for file in files {
_ = writeln!(stdout, "{file}");
}
}
pub fn print_summary(
action: Action,
root: &Path,
nb_files: usize,
nb_errors: usize,
nb_hooks_ran: usize,
) {
print_files_summary(action, root, nb_files, nb_errors);
print_hooks_summary(nb_hooks_ran);
}
pub fn print_files_summary(action: Action, root: &Path, nb_files: usize, nb_errors: usize) {
if nb_files + nb_errors == 0 {
println!("No config files found in '{}'.", root.display());
}
let mut stdout = io::stdout().lock();
_ = write!(
stdout,
"{action} {nb_files} file{}",
if nb_files == 1 { "" } else { "s" }
);
if nb_errors > 0 {
_ = write!(
stdout,
", {nb_errors} error{}",
if nb_errors == 1 { "" } else { "s" }
);
}
_ = writeln!(stdout, ".");
}
pub fn print_hooks_summary(nb_hooks_ran: usize) {
if nb_hooks_ran == 0 {
return;
}
println!(
"Ran {nb_hooks_ran} hook{}.",
if nb_hooks_ran == 1 { "" } else { "s" }
);
}