1use colored::*;
4use std::sync::atomic::{AtomicBool, AtomicU8, Ordering};
5
6static VERBOSITY: AtomicU8 = AtomicU8::new(0);
8static DEBUG_MODE: AtomicBool = AtomicBool::new(false);
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
12pub enum VerbosityLevel {
13 Normal = 0,
15 Verbose = 1,
17 Debug = 2,
19}
20
21pub fn init(verbose: bool, debug: bool) {
23 if debug {
24 VERBOSITY.store(VerbosityLevel::Debug as u8, Ordering::Relaxed);
25 DEBUG_MODE.store(true, Ordering::Relaxed);
26 } else if verbose {
27 VERBOSITY.store(VerbosityLevel::Verbose as u8, Ordering::Relaxed);
28 } else {
29 VERBOSITY.store(VerbosityLevel::Normal as u8, Ordering::Relaxed);
30 }
31}
32
33pub fn is_verbose() -> bool {
35 VERBOSITY.load(Ordering::Relaxed) >= VerbosityLevel::Verbose as u8
36}
37
38pub fn is_debug() -> bool {
40 DEBUG_MODE.load(Ordering::Relaxed)
41}
42
43pub fn success(message: &str) {
45 println!("{} {}", "✓".bright_green().bold(), message.bright_green());
46}
47
48pub fn error(message: &str) {
50 eprintln!("{} {}", "✗".bright_red().bold(), message.bright_red());
51}
52
53pub fn warning(message: &str) {
55 println!("{} {}", "⚠".bright_yellow().bold(), message.bright_yellow());
56}
57
58pub fn info(message: &str) {
60 println!("{} {}", "ℹ".bright_blue().bold(), message);
61}
62
63pub fn verbose(message: &str) {
65 if is_verbose() {
66 println!("{} {}", "→".bright_black(), message.bright_black());
67 }
68}
69
70pub fn debug(message: &str) {
72 if is_debug() {
73 println!("{} {}", "DEBUG:".bright_magenta().bold(), message.bright_black());
74 }
75}
76
77pub fn step(step: usize, total: usize, message: &str) {
79 println!(
80 "{} {}",
81 format!("[{}/{}]", step, total).bright_cyan().bold(),
82 message
83 );
84}
85
86pub fn header(message: &str) {
88 println!();
89 println!("{}", message.bright_white().bold());
90 println!("{}", "=".repeat(message.len()).bright_black());
91}
92
93pub fn subheader(message: &str) {
95 println!();
96 println!("{}", message.bright_white());
97 println!("{}", "-".repeat(message.len()).bright_black());
98}
99
100pub fn timing(operation: &str, duration_ms: u128) {
102 if is_verbose() {
103 println!(
104 "{} {} took {}",
105 "⏱".bright_black(),
106 operation.bright_black(),
107 format!("{}ms", duration_ms).bright_white()
108 );
109 }
110}
111
112pub fn file_size(path: &str, size_bytes: u64) {
114 if is_verbose() {
115 let size_str = if size_bytes < 1024 {
116 format!("{} bytes", size_bytes)
117 } else if size_bytes < 1024 * 1024 {
118 format!("{:.2} KB", size_bytes as f64 / 1024.0)
119 } else {
120 format!("{:.2} MB", size_bytes as f64 / (1024.0 * 1024.0))
121 };
122
123 println!(
124 "{} {} - {}",
125 "📄".bright_black(),
126 path.bright_black(),
127 size_str.bright_white()
128 );
129 }
130}
131
132pub fn debug_value<T: std::fmt::Debug>(label: &str, value: &T) {
134 if is_debug() {
135 println!(
136 "{} {} = {:?}",
137 "DEBUG:".bright_magenta().bold(),
138 label.bright_black(),
139 value
140 );
141 }
142}
143
144pub fn separator() {
146 if is_verbose() {
147 println!("{}", "─".repeat(60).bright_black());
148 }
149}
150