tcss_cli/
output.rs

1//! Output and logging utilities for TCSS CLI
2
3use colored::*;
4use std::sync::atomic::{AtomicBool, AtomicU8, Ordering};
5
6/// Global verbosity level
7static VERBOSITY: AtomicU8 = AtomicU8::new(0);
8static DEBUG_MODE: AtomicBool = AtomicBool::new(false);
9
10/// Verbosity levels
11#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
12pub enum VerbosityLevel {
13    /// Normal output only
14    Normal = 0,
15    /// Verbose output
16    Verbose = 1,
17    /// Debug output
18    Debug = 2,
19}
20
21/// Initialize the output system with verbosity settings
22pub 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
33/// Check if verbose mode is enabled
34pub fn is_verbose() -> bool {
35    VERBOSITY.load(Ordering::Relaxed) >= VerbosityLevel::Verbose as u8
36}
37
38/// Check if debug mode is enabled
39pub fn is_debug() -> bool {
40    DEBUG_MODE.load(Ordering::Relaxed)
41}
42
43/// Print a success message
44pub fn success(message: &str) {
45    println!("{} {}", "✓".bright_green().bold(), message.bright_green());
46}
47
48/// Print an error message
49pub fn error(message: &str) {
50    eprintln!("{} {}", "✗".bright_red().bold(), message.bright_red());
51}
52
53/// Print a warning message
54pub fn warning(message: &str) {
55    println!("{} {}", "⚠".bright_yellow().bold(), message.bright_yellow());
56}
57
58/// Print an info message
59pub fn info(message: &str) {
60    println!("{} {}", "ℹ".bright_blue().bold(), message);
61}
62
63/// Print a verbose message (only shown in verbose mode)
64pub fn verbose(message: &str) {
65    if is_verbose() {
66        println!("{} {}", "→".bright_black(), message.bright_black());
67    }
68}
69
70/// Print a debug message (only shown in debug mode)
71pub fn debug(message: &str) {
72    if is_debug() {
73        println!("{} {}", "DEBUG:".bright_magenta().bold(), message.bright_black());
74    }
75}
76
77/// Print a step message (for multi-step operations)
78pub fn step(step: usize, total: usize, message: &str) {
79    println!(
80        "{} {}",
81        format!("[{}/{}]", step, total).bright_cyan().bold(),
82        message
83    );
84}
85
86/// Print a header
87pub fn header(message: &str) {
88    println!();
89    println!("{}", message.bright_white().bold());
90    println!("{}", "=".repeat(message.len()).bright_black());
91}
92
93/// Print a subheader
94pub fn subheader(message: &str) {
95    println!();
96    println!("{}", message.bright_white());
97    println!("{}", "-".repeat(message.len()).bright_black());
98}
99
100/// Print timing information (only in verbose mode)
101pub 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
112/// Print file size information (only in verbose mode)
113pub 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
132/// Print debug information about a value
133pub 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
144/// Print a separator line
145pub fn separator() {
146    if is_verbose() {
147        println!("{}", "─".repeat(60).bright_black());
148    }
149}
150