zeitgeist_protocol/
temporal.rs1use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
7#[repr(u8)]
8pub enum Phase {
9 Idle = 0,
10 Approaching = 1,
11 Snap = 2,
12 Hold = 3,
13}
14
15impl From<u8> for Phase {
16 fn from(v: u8) -> Self {
17 match v {
18 0 => Phase::Idle,
19 1 => Phase::Approaching,
20 2 => Phase::Snap,
21 _ => Phase::Hold,
22 }
23 }
24}
25
26#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
28pub struct TemporalState {
29 pub beat_pos: f64,
31 pub phase: Phase,
33 pub rhythm_coherence: f64,
35}
36
37impl TemporalState {
38 pub fn new(beat_pos: f64, phase: Phase, rhythm_coherence: f64) -> Self {
39 Self { beat_pos, phase, rhythm_coherence }
40 }
41
42 pub fn default() -> Self {
43 Self {
44 beat_pos: 0.0,
45 phase: Phase::Idle,
46 rhythm_coherence: 1.0,
47 }
48 }
49
50 pub fn check_alignment(&self) -> Vec<String> {
52 let mut violations = Vec::new();
53 if !(0.0..=1.0).contains(&self.beat_pos) {
54 violations.push("temporal.beat_pos must be 0-1".into());
55 }
56 if !(0.0..=1.0).contains(&self.rhythm_coherence) {
57 violations.push("temporal.rhythm_coherence must be 0-1".into());
58 }
59 violations
60 }
61
62 pub fn merge(&self, other: &Self) -> Self {
65 Self {
66 beat_pos: self.beat_pos.max(other.beat_pos),
67 phase: std::cmp::max(self.phase, other.phase),
68 rhythm_coherence: self.rhythm_coherence.max(other.rhythm_coherence),
69 }
70 }
71}