hyperstack_server/websocket/
frame.rs

1use serde::{Deserialize, Serialize};
2
3/// Streaming mode for different data access patterns
4#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Hash)]
5#[serde(rename_all = "lowercase")]
6pub enum Mode {
7    /// Latest value only (watch semantics)
8    State,
9    /// Key-value with updates (map semantics)
10    Kv,
11    /// Append-only stream
12    Append,
13    /// Collection/list view
14    List,
15}
16
17/// Data frame sent over WebSocket
18#[derive(Debug, Clone, Serialize, Deserialize)]
19pub struct Frame {
20    pub mode: Mode,
21    #[serde(rename = "entity")]
22    pub export: String,
23    pub op: &'static str,
24    pub key: String,
25    pub data: serde_json::Value,
26}
27
28impl Frame {
29    pub fn entity(&self) -> &str {
30        &self.export
31    }
32
33    pub fn key(&self) -> &str {
34        &self.key
35    }
36}
37
38#[cfg(test)]
39mod tests {
40    use super::*;
41
42    #[test]
43    fn test_frame_entity_key_accessors() {
44        let frame = Frame {
45            mode: Mode::Kv,
46            export: "SettlementGame/kv".to_string(),
47            op: "upsert",
48            key: "123".to_string(),
49            data: serde_json::json!({}),
50        };
51
52        assert_eq!(frame.entity(), "SettlementGame/kv");
53        assert_eq!(frame.key(), "123");
54    }
55
56    #[test]
57    fn test_frame_serialization() {
58        let frame = Frame {
59            mode: Mode::Kv,
60            export: "SettlementGame/kv".to_string(),
61            op: "upsert",
62            key: "123".to_string(),
63            data: serde_json::json!({"gameId": "123"}),
64        };
65
66        let json = serde_json::to_value(&frame).unwrap();
67        assert_eq!(json["op"], "upsert");
68        assert_eq!(json["mode"], "kv");
69        assert_eq!(json["entity"], "SettlementGame/kv");
70        assert_eq!(json["key"], "123");
71    }
72}