use std::sync::atomic::{AtomicBool, Ordering};
static NO_COLOR: AtomicBool = AtomicBool::new(false);
static QUIET: AtomicBool = AtomicBool::new(false);
static VERBOSE: AtomicBool = AtomicBool::new(false);
static DEBUG: AtomicBool = AtomicBool::new(false);
pub fn init(no_color: bool, quiet: bool, verbose: bool, debug: bool) {
NO_COLOR.store(no_color, Ordering::Relaxed);
QUIET.store(quiet, Ordering::Relaxed);
VERBOSE.store(verbose, Ordering::Relaxed);
DEBUG.store(debug, Ordering::Relaxed);
if no_color {
colored::control::set_override(false);
}
}
#[allow(dead_code)] pub fn no_color() -> bool {
NO_COLOR.load(Ordering::Relaxed)
}
pub fn quiet() -> bool {
QUIET.load(Ordering::Relaxed)
}
pub fn verbose() -> bool {
VERBOSE.load(Ordering::Relaxed)
}
pub fn debug() -> bool {
DEBUG.load(Ordering::Relaxed)
}
pub fn log_verbose(message: &str) {
if verbose() || debug() {
eprintln!("{}", message);
}
}
#[allow(dead_code)] pub fn log_debug(message: &str) {
if debug() {
eprintln!("[DEBUG] {}", message);
}
}
pub fn log_request(method: &str, url: &str) {
if verbose() || debug() {
eprintln!("{} {}", method, url);
}
}
pub fn log_response(status: u16, url: &str) {
if verbose() || debug() {
eprintln!("{} {}", status, url);
}
}
#[allow(dead_code)] pub fn redact_secrets(text: &str) -> String {
let mut redacted = text.to_string();
let secret_pattern =
regex::Regex::new(r"(?i)(client[_-]?secret|secret[_-]?key|api[_-]?key)\s*[:=]\s*[^\s]+")
.unwrap();
redacted = secret_pattern
.replace_all(&redacted, "$1: [REDACTED]")
.to_string();
let token_pattern = regex::Regex::new(
r"(?i)(token|access[_-]?token|refresh[_-]?token|bearer)\s*[:=]\s*([A-Za-z0-9_-]{20,})",
)
.unwrap();
redacted = token_pattern
.replace_all(&redacted, "$1: [REDACTED]")
.to_string();
redacted
}