zero_operator_state/
vector.rs1use serde::{Deserialize, Serialize};
12
13#[derive(Debug, Clone, Copy, Default, PartialEq, Serialize, Deserialize)]
16pub struct Velocity {
17 pub last_1h: u32,
18 pub last_4h: u32,
19 pub last_24h: u32,
20 pub baseline_1h: Option<f64>,
24}
25
26impl Velocity {
27 #[must_use]
28 pub fn ratio_to_baseline(&self) -> Option<f64> {
29 self.baseline_1h
30 .filter(|b| *b > 0.0)
31 .map(|b| f64::from(self.last_1h) / b)
32 }
33}
34
35#[derive(Debug, Clone, Copy, Default, PartialEq, Serialize, Deserialize)]
37pub struct Deviation {
38 pub overrides_last_10: u32,
39 pub verdicts_last_10: u32,
40 pub overrides_last_50: u32,
41 pub verdicts_last_50: u32,
42}
43
44impl Deviation {
45 #[must_use]
47 pub fn rate_last_10(&self) -> f64 {
48 if self.verdicts_last_10 == 0 {
49 0.0
50 } else {
51 f64::from(self.overrides_last_10) / f64::from(self.verdicts_last_10)
52 }
53 }
54}
55
56#[derive(Debug, Clone, Copy, Default, PartialEq, Serialize, Deserialize)]
58pub struct Session {
59 pub active_duration_ms: u64,
61 pub longest_focus_ms: u64,
63 pub since_last_break_ms: u64,
65}
66
67#[derive(Debug, Clone, Copy, Default, PartialEq, Serialize, Deserialize)]
70pub struct LossReaction {
71 pub median_last_10_ms: u64,
73 pub fastest_session_ms: u64,
75 pub baseline_ms: Option<u64>,
77}
78
79#[derive(Debug, Clone, Copy, Default, PartialEq, Serialize, Deserialize)]
81pub struct ReEntry {
82 pub within_15m: u32,
83 pub within_30m: u32,
84 pub within_2h: u32,
85}
86
87#[derive(Debug, Clone, Copy, Default, PartialEq, Serialize, Deserialize)]
89pub struct SleepProxy {
90 pub hours_since_rest_ended: Option<u32>,
91}
92
93#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
96pub struct StateVector {
97 pub velocity: Velocity,
98 pub deviation: Deviation,
99 pub session: Session,
100 pub loss_reaction: LossReaction,
101 pub re_entry: ReEntry,
102 pub sleep_proxy: SleepProxy,
103 pub on_break: bool,
107}