1use std::cell::Cell;
13
14thread_local! {
15 static OPERATIONS: Cell<bool> = const { Cell::new(false) };
16}
17
18pub fn with_operation_spans<R>(enabled: bool, f: impl FnOnce() -> R) -> R {
20 struct Restore(bool);
21 impl Drop for Restore {
22 fn drop(&mut self) {
23 OPERATIONS.with(|flag| flag.set(self.0));
24 }
25 }
26 let prev = OPERATIONS.with(|flag| flag.replace(enabled));
27 let _restore = Restore(prev);
28 f()
29}
30
31pub fn operations_enabled() -> bool {
33 OPERATIONS.with(Cell::get)
34}
35
36#[cfg(test)]
37mod tests {
38 use super::*;
39
40 #[test]
41 fn off_by_default() {
42 assert!(!operations_enabled());
43 }
44
45 #[test]
46 fn on_inside_scope() {
47 with_operation_spans(true, || {
48 assert!(operations_enabled());
49 });
50 assert!(!operations_enabled());
51 }
52
53 #[test]
54 fn restores_after_panic() {
55 let _ = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
56 with_operation_spans(true, || panic!("boom"));
57 }));
58 assert!(!operations_enabled());
59 }
60}