Skip to main content

rumdl_lib/code_block_tools/
run_state.rs

1//! Invocation-scoped accounting, shared by files and tool phases.
2
3use std::collections::BTreeMap;
4use std::sync::Mutex;
5use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
6
7#[derive(Debug, Default)]
8pub struct RunState {
9    executions: AtomicUsize,
10    aborted: AtomicBool,
11    cached_checks: AtomicUsize,
12    warnings: Mutex<BTreeMap<String, String>>,
13}
14
15// Operational state is excluded from configuration serialization and identity.
16impl PartialEq for RunState {
17    fn eq(&self, _other: &Self) -> bool {
18        true
19    }
20}
21impl Eq for RunState {}
22
23impl RunState {
24    pub fn abort(&self) {
25        self.aborted.store(true, Ordering::Relaxed);
26    }
27    pub fn aborted(&self) -> bool {
28        self.aborted.load(Ordering::Relaxed)
29    }
30    pub fn record_execution(&self) {
31        self.executions.fetch_add(1, Ordering::Relaxed);
32    }
33    pub fn record_cached_check(&self) {
34        self.cached_checks.fetch_add(1, Ordering::Relaxed);
35    }
36    pub fn checked_anything(&self) -> bool {
37        self.executions.load(Ordering::Relaxed) > 0 || self.cached_checks.load(Ordering::Relaxed) > 0
38    }
39    pub fn warn(&self, key: String, message: String) {
40        self.warnings
41            .lock()
42            .unwrap_or_else(std::sync::PoisonError::into_inner)
43            .entry(key)
44            .or_insert(message);
45    }
46    pub fn warnings(&self) -> Vec<String> {
47        self.warnings
48            .lock()
49            .unwrap_or_else(std::sync::PoisonError::into_inner)
50            .values()
51            .cloned()
52            .collect()
53    }
54}