1use std::sync::OnceLock;
7
8#[derive(Debug, Clone, PartialEq, Eq)]
9pub struct Timing {
10 pub poll_ms: u64,
12 pub wake_bound_ms: u64,
14 pub probe_ms: u32,
16 pub focus_retries: u32,
18 pub press_focus_ms: u64,
20 pub type_focus_ms: u64,
22 pub segment_chars: usize,
24 pub modifier_wait_ms: u64,
26 pub lock_wait_ms: u32,
28}
29
30impl Default for Timing {
31 fn default() -> Self {
32 Self {
33 poll_ms: 100,
34 wake_bound_ms: 1600,
35 probe_ms: 60,
36 focus_retries: 3,
37 press_focus_ms: 120,
38 type_focus_ms: 150,
39 segment_chars: 32,
40 modifier_wait_ms: 1500,
41 lock_wait_ms: 3000,
42 }
43 }
44}
45
46fn env_num<T: std::str::FromStr>(name: &str, default: T) -> T {
47 std::env::var(name)
48 .ok()
49 .and_then(|v| v.trim().parse().ok())
50 .unwrap_or(default)
51}
52
53impl Timing {
54 pub fn load() -> &'static Timing {
56 static T: OnceLock<Timing> = OnceLock::new();
57 T.get_or_init(|| {
58 let d = Timing::default();
59 Timing {
60 poll_ms: env_num("ACTL_POLL_MS", d.poll_ms),
61 wake_bound_ms: env_num("ACTL_WAKE_BOUND_MS", d.wake_bound_ms),
62 probe_ms: env_num("ACTL_PROBE_MS", d.probe_ms),
63 focus_retries: env_num("ACTL_FOCUS_RETRIES", d.focus_retries),
64 press_focus_ms: env_num("ACTL_PRESS_FOCUS_MS", d.press_focus_ms),
65 type_focus_ms: env_num("ACTL_TYPE_FOCUS_MS", d.type_focus_ms),
66 segment_chars: env_num("ACTL_SEGMENT_CHARS", d.segment_chars),
67 modifier_wait_ms: env_num("ACTL_MODIFIER_WAIT_MS", d.modifier_wait_ms),
68 lock_wait_ms: env_num("ACTL_LOCK_WAIT_MS", d.lock_wait_ms),
69 }
70 })
71 }
72}
73
74#[cfg(test)]
75mod tests {
76 use super::*;
77
78 #[test]
79 fn defaults_match_production_values() {
80 let d = Timing::default();
81 assert_eq!(d.poll_ms, 100); assert_eq!(d.wake_bound_ms, 1600); assert_eq!(d.segment_chars, 32);
84 assert_eq!(d.lock_wait_ms, 3000);
85 assert_eq!(d.modifier_wait_ms, 1500);
86 assert_eq!(d.focus_retries, 3);
87 }
88
89 #[test]
90 fn env_num_parses_and_falls_back() {
91 assert_eq!(env_num::<u64>("_ACTL_TEST_ABSENT_", 42), 42);
92 assert_eq!(env_num::<u64>("PATH", 42), 42); }
95}