1use std::sync::atomic::{AtomicBool, Ordering};
8
9static DEBUG_ENABLED: AtomicBool = AtomicBool::new(false);
10
11pub fn init() {
13 let enabled = cfg!(debug_assertions) || std::env::var("SPIKARD_DEBUG").is_ok() || std::env::var("DEBUG").is_ok();
14
15 eprintln!(
16 "[spikard-http::debug] init() called, cfg!(debug_assertions)={}, DEBUG={}, enabled={}",
17 cfg!(debug_assertions),
18 std::env::var("DEBUG").is_ok(),
19 enabled
20 );
21
22 DEBUG_ENABLED.store(enabled, Ordering::Relaxed);
23
24 if enabled {
25 eprintln!("[spikard-http] Debug logging enabled");
26 }
27}
28
29#[inline]
31pub fn is_enabled() -> bool {
32 DEBUG_ENABLED.load(Ordering::Relaxed)
33}
34
35#[macro_export]
37macro_rules! debug_log {
38 ($($arg:tt)*) => {
39 if $crate::debug::is_enabled() {
40 eprintln!("[spikard-http] {}", format!($($arg)*));
41 }
42 };
43}
44
45#[macro_export]
47macro_rules! debug_log_module {
48 ($module:expr, $($arg:tt)*) => {
49 if $crate::debug::is_enabled() {
50 eprintln!("[spikard-http::{}] {}", $module, format!($($arg)*));
51 }
52 };
53}
54
55#[macro_export]
57macro_rules! debug_log_value {
58 ($name:expr, $value:expr) => {
59 if $crate::debug::is_enabled() {
60 eprintln!("[spikard-http] {} = {:?}", $name, $value);
61 }
62 };
63}
64
65#[cfg(test)]
66mod tests {
67 use super::*;
68 use std::sync::Mutex;
69 use std::sync::atomic::Ordering;
70
71 static FLAG_LOCK: Mutex<()> = Mutex::new(());
72
73 struct DebugFlagGuard {
74 previous_flag: bool,
75 previous_env: Option<String>,
76 }
77
78 impl Drop for DebugFlagGuard {
79 fn drop(&mut self) {
80 DEBUG_ENABLED.store(self.previous_flag, Ordering::Relaxed);
81 if let Some(prev) = &self.previous_env {
82 unsafe { std::env::set_var("SPIKARD_DEBUG", prev) };
83 } else {
84 unsafe { std::env::remove_var("SPIKARD_DEBUG") };
85 }
86 }
87 }
88
89 #[test]
90 fn init_sets_debug_enabled_in_tests() {
91 let _lock = FLAG_LOCK.lock().unwrap();
92 let previous = DEBUG_ENABLED.load(Ordering::Relaxed);
93 let previous_env = std::env::var("SPIKARD_DEBUG").ok();
94 let _guard = DebugFlagGuard {
95 previous_flag: previous,
96 previous_env,
97 };
98
99 unsafe { std::env::set_var("SPIKARD_DEBUG", "1") };
100
101 init();
102 assert!(is_enabled(), "init should enable debug when SPIKARD_DEBUG is set");
103 }
104
105 #[test]
106 fn macros_follow_debug_flag() {
107 let _lock = FLAG_LOCK.lock().unwrap();
108 let previous = DEBUG_ENABLED.load(Ordering::Relaxed);
109 let previous_env = std::env::var("SPIKARD_DEBUG").ok();
110 let _guard = DebugFlagGuard {
111 previous_flag: previous,
112 previous_env,
113 };
114
115 DEBUG_ENABLED.store(false, Ordering::Relaxed);
116 debug_log!("disabled branch");
117 debug_log_module!("core", "disabled");
118 debug_log_value!("counter", 0_u8);
119 assert!(!is_enabled());
120
121 DEBUG_ENABLED.store(true, Ordering::Relaxed);
122 debug_log!("enabled branch {}", 1);
123 debug_log_module!("core", "enabled");
124 debug_log_value!("counter", 2_i32);
125 assert!(is_enabled());
126 }
127}