use std::sync::atomic::{AtomicU64, Ordering}; #[cfg(feature = "debug")] use std::time::{SystemTime, UNIX_EPOCH}; static NEXT_TRACE_ID: AtomicU64 = AtomicU64::new(1); pub fn next_trace_id(prefix: &str) -> String { let id = NEXT_TRACE_ID.fetch_add(1, Ordering::Relaxed); format!("{prefix}-{id:06}") } #[cfg(feature = "debug")] pub fn emit(module: &str, line: u32, message: String) { let millis = SystemTime::now() .duration_since(UNIX_EPOCH) .map(|duration| duration.as_millis()) .unwrap_or_default(); eprintln!("[debug][{millis}][{module}:{line}] {message}"); } pub fn preview(value: &str, limit: usize) -> String { if value.len() <= limit { return value.to_string(); } let mut end = limit; while !value.is_char_boundary(end) { end -= 1; } format!("{}...", &value[..end]) } #[macro_export] macro_rules! flow_debug { ($($arg:tt)*) => {{ #[cfg(feature = "debug")] { $crate::util::flow_debug::emit(module_path!(), line!(), format!($($arg)*)); } }}; }