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    /// Append-only stream
10    Append,
11    /// Collection/list view (also used for key-value lookups)
12    List,
13}
14
15/// Data frame sent over WebSocket
16#[derive(Debug, Clone, Serialize, Deserialize)]
17pub struct Frame {
18    pub mode: Mode,
19    #[serde(rename = "entity")]
20    pub export: String,
21    pub op: &'static str,
22    pub key: String,
23    pub data: serde_json::Value,
24}
25
26impl Frame {
27    pub fn entity(&self) -> &str {
28        &self.export
29    }
30
31    pub fn key(&self) -> &str {
32        &self.key
33    }
34}
35
36#[cfg(test)]
37mod tests {
38    use super::*;
39
40    #[test]
41    fn test_frame_entity_key_accessors() {
42        let frame = Frame {
43            mode: Mode::List,
44            export: "SettlementGame/list".to_string(),
45            op: "upsert",
46            key: "123".to_string(),
47            data: serde_json::json!({}),
48        };
49
50        assert_eq!(frame.entity(), "SettlementGame/list");
51        assert_eq!(frame.key(), "123");
52    }
53
54    #[test]
55    fn test_frame_serialization() {
56        let frame = Frame {
57            mode: Mode::List,
58            export: "SettlementGame/list".to_string(),
59            op: "upsert",
60            key: "123".to_string(),
61            data: serde_json::json!({"gameId": "123"}),
62        };
63
64        let json = serde_json::to_value(&frame).unwrap();
65        assert_eq!(json["op"], "upsert");
66        assert_eq!(json["mode"], "list");
67        assert_eq!(json["entity"], "SettlementGame/list");
68        assert_eq!(json["key"], "123");
69    }
70}