use std::sync::OnceLock;
use std::time::Instant;
pub fn enabled() -> bool {
static ON: OnceLock<bool> = OnceLock::new();
*ON.get_or_init(|| {
std::env::var("ACTL_TRACE")
.map(|v| !v.is_empty() && v != "0")
.unwrap_or(false)
})
}
pub fn stage(stage: &str, started: Instant) {
if enabled() {
eprintln!("[actl-trace] {stage} {}ms", started.elapsed().as_millis());
}
}
pub struct TraceScope {
stage: &'static str,
started: Instant,
}
pub fn scope(stage: &'static str) -> TraceScope {
TraceScope {
stage,
started: Instant::now(),
}
}
impl Drop for TraceScope {
fn drop(&mut self) {
stage(self.stage, self.started);
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn disabled_by_default_and_stage_is_silent_noop() {
let ok = std::panic::catch_unwind(|| {
stage("test.point", Instant::now());
let _t = scope("test.scope");
});
assert!(ok.is_ok());
}
#[test]
fn scope_drop_invokes_stage_without_panic() {
let _t = scope("test.lifetime");
drop(_t);
}
}