hyperstack_server/websocket/
subscription.rs1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Serialize, Deserialize)]
5pub struct Subscription {
6 pub view: String,
7 #[serde(skip_serializing_if = "Option::is_none")]
8 pub key: Option<String>,
9 #[serde(skip_serializing_if = "Option::is_none")]
10 pub partition: Option<String>,
11}
12
13impl Subscription {
14 pub fn matches_view(&self, view_id: &str) -> bool {
15 self.view == view_id
16 }
17
18 pub fn matches_key(&self, key: &str) -> bool {
19 self.key.as_ref().is_none_or(|k| k == key)
20 }
21
22 pub fn matches(&self, view_id: &str, key: &str) -> bool {
23 self.matches_view(view_id) && self.matches_key(key)
24 }
25}
26
27#[cfg(test)]
28mod tests {
29 use super::*;
30 use serde_json::json;
31
32 #[test]
33 fn test_subscription_parse() {
34 let json = json!({
35 "view": "SettlementGame/list",
36 "key": "835"
37 });
38
39 let sub: Subscription = serde_json::from_value(json).unwrap();
40 assert_eq!(sub.view, "SettlementGame/list");
41 assert_eq!(sub.key, Some("835".to_string()));
42 }
43
44 #[test]
45 fn test_subscription_no_key() {
46 let json = json!({
47 "view": "SettlementGame/list"
48 });
49
50 let sub: Subscription = serde_json::from_value(json).unwrap();
51 assert_eq!(sub.view, "SettlementGame/list");
52 assert!(sub.key.is_none());
53 }
54
55 #[test]
56 fn test_subscription_matches() {
57 let sub = Subscription {
58 view: "SettlementGame/list".to_string(),
59 key: Some("835".to_string()),
60 partition: None,
61 };
62
63 assert!(sub.matches("SettlementGame/list", "835"));
64 assert!(!sub.matches("SettlementGame/list", "836"));
65 assert!(!sub.matches("SettlementGame/state", "835"));
66 }
67
68 #[test]
69 fn test_subscription_matches_all_keys() {
70 let sub = Subscription {
71 view: "SettlementGame/list".to_string(),
72 key: None,
73 partition: None,
74 };
75
76 assert!(sub.matches("SettlementGame/list", "835"));
77 assert!(sub.matches("SettlementGame/list", "836"));
78 assert!(!sub.matches("SettlementGame/state", "835"));
79 }
80}