hyperstack_server/websocket/
frame.rs1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Hash)]
5#[serde(rename_all = "lowercase")]
6pub enum Mode {
7 State,
9 Append,
11 List,
13}
14
15#[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 #[serde(skip_serializing_if = "Vec::is_empty", default)]
25 pub append: Vec<String>,
26}
27
28#[derive(Debug, Clone, Serialize, Deserialize)]
30pub struct SnapshotEntity {
31 pub key: String,
32 pub data: serde_json::Value,
33}
34
35#[derive(Debug, Clone, Serialize, Deserialize)]
37pub struct SnapshotFrame {
38 pub mode: Mode,
39 #[serde(rename = "entity")]
40 pub export: String,
41 pub op: &'static str,
42 pub data: Vec<SnapshotEntity>,
43}
44
45impl Frame {
46 pub fn entity(&self) -> &str {
47 &self.export
48 }
49
50 pub fn key(&self) -> &str {
51 &self.key
52 }
53}
54
55#[cfg(test)]
56mod tests {
57 use super::*;
58
59 #[test]
60 fn test_frame_entity_key_accessors() {
61 let frame = Frame {
62 mode: Mode::List,
63 export: "SettlementGame/list".to_string(),
64 op: "upsert",
65 key: "123".to_string(),
66 data: serde_json::json!({}),
67 append: vec![],
68 };
69
70 assert_eq!(frame.entity(), "SettlementGame/list");
71 assert_eq!(frame.key(), "123");
72 }
73
74 #[test]
75 fn test_frame_serialization() {
76 let frame = Frame {
77 mode: Mode::List,
78 export: "SettlementGame/list".to_string(),
79 op: "upsert",
80 key: "123".to_string(),
81 data: serde_json::json!({"gameId": "123"}),
82 append: vec![],
83 };
84
85 let json = serde_json::to_value(&frame).unwrap();
86 assert_eq!(json["op"], "upsert");
87 assert_eq!(json["mode"], "list");
88 assert_eq!(json["entity"], "SettlementGame/list");
89 assert_eq!(json["key"], "123");
90 }
91}