use std::env;
pub fn is_trace_enabled() -> bool {
let trace_env = env::var("COMMAND_STREAM_TRACE").ok();
let verbose_env = env::var("COMMAND_STREAM_VERBOSE")
.map(|v| v == "true")
.unwrap_or(false);
match trace_env.as_deref() {
Some("false") => false,
Some("true") => true,
_ => verbose_env,
}
}
pub fn trace(category: &str, message: &str) {
if !is_trace_enabled() {
return;
}
let timestamp = chrono::Utc::now().to_rfc3339();
eprintln!("[TRACE {}] [{}] {}", timestamp, category, message);
}
pub fn trace_lazy<F>(category: &str, message_fn: F)
where
F: FnOnce() -> String,
{
if !is_trace_enabled() {
return;
}
trace(category, &message_fn());
}
#[cfg(test)]
mod tests {
use super::*;
use std::env;
use std::sync::Mutex;
static ENV_MUTEX: Mutex<()> = Mutex::new(());
struct EnvGuard {
trace_value: Option<String>,
verbose_value: Option<String>,
}
impl EnvGuard {
fn new() -> Self {
EnvGuard {
trace_value: env::var("COMMAND_STREAM_TRACE").ok(),
verbose_value: env::var("COMMAND_STREAM_VERBOSE").ok(),
}
}
}
impl Drop for EnvGuard {
fn drop(&mut self) {
match &self.trace_value {
Some(v) => env::set_var("COMMAND_STREAM_TRACE", v),
None => env::remove_var("COMMAND_STREAM_TRACE"),
}
match &self.verbose_value {
Some(v) => env::set_var("COMMAND_STREAM_VERBOSE", v),
None => env::remove_var("COMMAND_STREAM_VERBOSE"),
}
}
}
#[test]
fn test_trace_disabled_by_default() {
let _lock = ENV_MUTEX.lock().unwrap();
let _guard = EnvGuard::new();
env::remove_var("COMMAND_STREAM_TRACE");
env::remove_var("COMMAND_STREAM_VERBOSE");
assert!(!is_trace_enabled());
}
#[test]
fn test_trace_enabled_by_verbose() {
let _lock = ENV_MUTEX.lock().unwrap();
let _guard = EnvGuard::new();
env::remove_var("COMMAND_STREAM_TRACE");
env::set_var("COMMAND_STREAM_VERBOSE", "true");
assert!(is_trace_enabled());
}
#[test]
fn test_trace_explicit_true() {
let _lock = ENV_MUTEX.lock().unwrap();
let _guard = EnvGuard::new();
env::remove_var("COMMAND_STREAM_VERBOSE");
env::set_var("COMMAND_STREAM_TRACE", "true");
assert!(is_trace_enabled());
}
#[test]
fn test_trace_explicit_false_overrides_verbose() {
let _lock = ENV_MUTEX.lock().unwrap();
let _guard = EnvGuard::new();
env::set_var("COMMAND_STREAM_TRACE", "false");
env::set_var("COMMAND_STREAM_VERBOSE", "true");
assert!(!is_trace_enabled());
}
}