1use std::sync::atomic::{AtomicBool, Ordering};
10use std::time::Instant;
11
12static ENABLED: AtomicBool = AtomicBool::new(false);
13
14pub(crate) fn enable_from(flag: bool) {
17 let on = flag || std::env::var_os("RQ_LOG").is_some();
18 ENABLED.store(on, Ordering::Relaxed);
19}
20
21pub(crate) fn enabled() -> bool {
23 ENABLED.load(Ordering::Relaxed)
24}
25
26pub(crate) fn abbrev(path: &std::path::Path) -> String {
28 let s = path.display().to_string();
29 match std::env::var_os("HOME") {
30 Some(home) if !home.is_empty() => match s.strip_prefix(&*home.to_string_lossy()) {
31 Some(rest) => format!("~{rest}"),
32 None => s,
33 },
34 _ => s,
35 }
36}
37
38#[macro_export]
40macro_rules! trace {
41 ($($arg:tt)*) => {
42 if $crate::trace::enabled() {
43 eprintln!("rq: {}", format_args!($($arg)*));
44 }
45 };
46}
47
48pub(crate) struct Timer {
51 label: &'static str,
52 start: Option<Instant>,
53}
54
55impl Timer {
56 pub(crate) fn start(label: &'static str) -> Self {
57 Self {
58 label,
59 start: enabled().then(Instant::now),
60 }
61 }
62}
63
64impl Drop for Timer {
65 fn drop(&mut self) {
66 if let Some(start) = self.start {
67 eprintln!("rq: {} ({} ms)", self.label, start.elapsed().as_millis());
68 }
69 }
70}