pub mod crypto; pub mod editor; pub mod formatter; pub mod keyring; pub mod validators; use anyhow::{Context, Result}; use colored::Colorize; use std::io::{self, Write}; /// Print success message pub fn print_success(msg: &str) { println!("{} {}", "✓".green().bold(), msg); } /// Print error message pub fn print_error(msg: &str) { eprintln!("{} {}", "✗".red().bold(), msg); } /// Print warning message pub fn print_warning(msg: &str) { println!("{} {}", "⚠".yellow().bold(), msg); } /// Print info message pub fn print_info(msg: &str) { println!("{} {}", "ℹ".blue().bold(), msg); } /// Confirm action with user pub fn confirm(prompt: &str) -> Result { print!("{} [y/N] ", prompt); io::stdout().flush()?; let mut input = String::new(); io::stdin().read_line(&mut input)?; Ok(input.trim().to_lowercase().starts_with('y')) } /// Get user input pub fn input(prompt: &str) -> Result { print!("{}: ", prompt); io::stdout().flush()?; let mut input = String::new(); io::stdin().read_line(&mut input)?; Ok(input.trim().to_string()) } /// Get password input (hidden) pub fn password_input(prompt: &str) -> Result { use dialoguer::Password; Password::new() .with_prompt(prompt) .interact() .context("Failed to read password") } /// Check if running in a terminal pub fn is_terminal() -> bool { atty::is(atty::Stream::Stdout) } /// Format duration in human-readable format pub fn format_duration(secs: u64) -> String { if secs < 60 { format!("{}s", secs) } else if secs < 3600 { format!("{}m {}s", secs / 60, secs % 60) } else { format!("{}h {}m", secs / 3600, (secs % 3600) / 60) } }