Skip to main content

hm_exec/
capabilities.rs

1//! Runtime capability introspection. The CLI consults this BEFORE `start` to
2//! validate flags (e.g. reject `--parallelism` on an observer backend) and to
3//! phrase output (e.g. print a watch URL only when `provides_watch_url`).
4//! `#[non_exhaustive]`: new capabilities default off; old backends stay valid.
5
6#[derive(Debug, Clone, Copy)]
7#[non_exhaustive]
8// Each field is an independent yes/no capability; a state machine would obscure
9// orthogonal combinations (e.g. local can honor parallelism AND enforce timeout).
10#[allow(clippy::struct_excessive_bools)]
11pub struct Capabilities {
12    pub honors_parallelism: bool,
13    pub honors_keep_going: bool,
14    pub is_observer: bool, // submits + watches (cloud) vs executes (local)
15    pub reports_cache_hits: bool,
16    pub supports_no_watch: bool,
17    pub provides_watch_url: bool,
18    pub enforces_timeout: bool,
19}
20
21impl Capabilities {
22    #[must_use]
23    pub const fn none() -> Self {
24        Self {
25            honors_parallelism: false,
26            honors_keep_going: false,
27            is_observer: false,
28            reports_cache_hits: false,
29            supports_no_watch: false,
30            provides_watch_url: false,
31            enforces_timeout: false,
32        }
33    }
34
35    #[must_use]
36    pub const fn local() -> Self {
37        Self {
38            honors_parallelism: true,
39            honors_keep_going: true,
40            is_observer: false,
41            reports_cache_hits: true,
42            supports_no_watch: false,
43            provides_watch_url: false,
44            enforces_timeout: false, // TODO(timeout): local scheduler ignores RunOptions.timeout
45        }
46    }
47
48    #[must_use]
49    pub const fn cloud() -> Self {
50        Self {
51            honors_parallelism: false,
52            honors_keep_going: false,
53            is_observer: true,
54            reports_cache_hits: false,
55            supports_no_watch: true,
56            provides_watch_url: true,
57            enforces_timeout: false,
58        }
59    }
60}
61
62#[cfg(test)]
63mod tests {
64    use super::*;
65
66    #[test]
67    fn presets_differ() {
68        assert!(Capabilities::local().honors_parallelism);
69        assert!(!Capabilities::local().is_observer);
70        assert!(Capabilities::cloud().is_observer);
71        assert!(Capabilities::cloud().provides_watch_url);
72        assert!(!Capabilities::cloud().honors_parallelism);
73    }
74}