use std::sync::atomic::{AtomicBool, Ordering};
static DEBUG_ENABLED: AtomicBool = AtomicBool::new(false);
pub fn init() {
let enabled = cfg!(debug_assertions) || std::env::var("SPIKARD_DEBUG").is_ok() || std::env::var("DEBUG").is_ok();
eprintln!(
"[spikard-http::debug] init() called, cfg!(debug_assertions)={}, DEBUG={}, enabled={}",
cfg!(debug_assertions),
std::env::var("DEBUG").is_ok(),
enabled
);
DEBUG_ENABLED.store(enabled, Ordering::Relaxed);
if enabled {
eprintln!("[spikard-http] Debug logging enabled");
}
}
#[inline]
pub fn is_enabled() -> bool {
DEBUG_ENABLED.load(Ordering::Relaxed)
}
#[macro_export]
macro_rules! debug_log {
($($arg:tt)*) => {
if $crate::debug::is_enabled() {
eprintln!("[spikard-http] {}", format!($($arg)*));
}
};
}
#[macro_export]
macro_rules! debug_log_module {
($module:expr, $($arg:tt)*) => {
if $crate::debug::is_enabled() {
eprintln!("[spikard-http::{}] {}", $module, format!($($arg)*));
}
};
}
#[macro_export]
macro_rules! debug_log_value {
($name:expr, $value:expr) => {
if $crate::debug::is_enabled() {
eprintln!("[spikard-http] {} = {:?}", $name, $value);
}
};
}
#[cfg(test)]
mod tests {
use super::*;
use std::sync::Mutex;
use std::sync::atomic::Ordering;
static FLAG_LOCK: Mutex<()> = Mutex::new(());
struct DebugFlagGuard {
previous_flag: bool,
previous_env: Option<String>,
}
impl Drop for DebugFlagGuard {
fn drop(&mut self) {
DEBUG_ENABLED.store(self.previous_flag, Ordering::Relaxed);
if let Some(prev) = &self.previous_env {
unsafe { std::env::set_var("SPIKARD_DEBUG", prev) };
} else {
unsafe { std::env::remove_var("SPIKARD_DEBUG") };
}
}
}
#[test]
fn init_enables_debug_when_requested() {
let _lock = FLAG_LOCK.lock().unwrap();
let previous = DEBUG_ENABLED.load(Ordering::Relaxed);
let previous_env = std::env::var("SPIKARD_DEBUG").ok();
let _guard = DebugFlagGuard {
previous_flag: previous,
previous_env,
};
unsafe { std::env::set_var("SPIKARD_DEBUG", "1") };
init();
assert!(is_enabled(), "init should enable debug in test builds");
}
#[test]
fn macros_respect_debug_flag() {
let _lock = FLAG_LOCK.lock().unwrap();
let previous = DEBUG_ENABLED.load(Ordering::Relaxed);
let previous_env = std::env::var("SPIKARD_DEBUG").ok();
let _guard = DebugFlagGuard {
previous_flag: previous,
previous_env,
};
DEBUG_ENABLED.store(false, Ordering::Relaxed);
debug_log!("should not print while disabled");
debug_log_module!("middleware", "disabled branch");
debug_log_value!("key", 1_u8);
assert!(!is_enabled());
DEBUG_ENABLED.store(true, Ordering::Relaxed);
debug_log!("now printing {}", 2);
debug_log_module!("router", "enabled branch");
debug_log_value!("value", 3_i32);
assert!(is_enabled());
}
}