ferro_broadcast/
message.rs1use serde::{Deserialize, Serialize};
4use serde_json::Value;
5
6#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct BroadcastMessage {
9 pub event: String,
11 pub channel: String,
13 pub data: Value,
15}
16
17impl BroadcastMessage {
18 pub fn new(channel: impl Into<String>, event: impl Into<String>, data: impl Serialize) -> Self {
20 Self {
21 channel: channel.into(),
22 event: event.into(),
23 data: serde_json::to_value(data).unwrap_or(Value::Null),
24 }
25 }
26
27 pub fn with_data(channel: impl Into<String>, event: impl Into<String>, data: Value) -> Self {
29 Self {
30 channel: channel.into(),
31 event: event.into(),
32 data,
33 }
34 }
35
36 pub fn to_json(&self) -> Result<String, serde_json::Error> {
38 serde_json::to_string(self)
39 }
40}
41
42#[derive(Debug, Clone, Serialize, Deserialize)]
44#[serde(tag = "type", rename_all = "snake_case")]
45pub enum ClientMessage {
46 Subscribe {
48 channel: String,
49 #[serde(default)]
50 auth: Option<String>,
51 },
52 Unsubscribe { channel: String },
54 Whisper {
56 channel: String,
57 event: String,
58 data: Value,
59 },
60 Ping,
62}
63
64#[derive(Debug, Clone, Serialize, Deserialize)]
66#[serde(tag = "type", rename_all = "snake_case")]
67pub enum ServerMessage {
68 Connected { socket_id: String },
70 Subscribed { channel: String },
72 SubscriptionError { channel: String, error: String },
74 Unsubscribed { channel: String },
76 Event(BroadcastMessage),
78 MemberAdded {
80 channel: String,
81 user_id: String,
82 user_info: Value,
83 },
84 MemberRemoved { channel: String, user_id: String },
86 Pong,
88 Error { message: String },
90}
91
92impl ServerMessage {
93 pub fn to_json(&self) -> Result<String, serde_json::Error> {
95 serde_json::to_string(self)
96 }
97}
98
99#[cfg(test)]
100mod tests {
101 use super::*;
102
103 #[test]
104 fn test_broadcast_message() {
105 let msg = BroadcastMessage::new("orders.1", "OrderUpdated", serde_json::json!({"id": 1}));
106 assert_eq!(msg.channel, "orders.1");
107 assert_eq!(msg.event, "OrderUpdated");
108 }
109
110 #[test]
111 fn test_client_message_serialize() {
112 let msg = ClientMessage::Subscribe {
113 channel: "private-orders.1".into(),
114 auth: Some("auth_token".into()),
115 };
116 let json = serde_json::to_string(&msg).unwrap();
117 assert!(json.contains("subscribe"));
118 assert!(json.contains("private-orders.1"));
119 }
120
121 #[test]
122 fn test_server_message_serialize() {
123 let msg = ServerMessage::Connected {
124 socket_id: "abc123".into(),
125 };
126 let json = serde_json::to_string(&msg).unwrap();
127 assert!(json.contains("connected"));
128 assert!(json.contains("abc123"));
129 }
130}