1use serde::Deserialize;
2
3#[derive(Debug, Clone, Deserialize)]
5pub(crate) struct PusherMessage {
6 pub event: String,
7 pub data: String,
8 #[serde(default)]
9 pub channel: Option<String>,
10}
11
12#[derive(Debug, Clone)]
16pub struct PusherEvent {
17 pub event: String,
19 pub channel: Option<String>,
21 pub data: String,
23}
24
25#[derive(Debug, Clone, Deserialize)]
27pub struct LiveChatMessage {
28 pub id: String,
30
31 #[serde(default)]
33 pub chatroom_id: Option<u64>,
34
35 pub content: String,
37
38 #[serde(rename = "type")]
40 pub r#type: String,
41
42 #[serde(default)]
44 pub created_at: Option<String>,
45
46 pub sender: ChatSender,
48
49 #[serde(default)]
51 pub metadata: Option<ChatMessageMetadata>,
52}
53
54#[derive(Debug, Clone, Deserialize)]
56pub struct ChatMessageMetadata {
57 #[serde(default)]
59 pub original_sender: Option<OriginalSender>,
60
61 #[serde(default)]
63 pub original_message: Option<OriginalMessage>,
64}
65
66#[derive(Debug, Clone, Deserialize)]
68pub struct OriginalSender {
69 pub username: String,
70}
71
72#[derive(Debug, Clone, Deserialize)]
74pub struct OriginalMessage {
75 pub content: String,
76}
77
78#[derive(Debug, Clone, Deserialize)]
80pub struct ChatSender {
81 pub id: u64,
83
84 pub username: String,
86
87 #[serde(default)]
89 pub slug: Option<String>,
90
91 pub identity: ChatIdentity,
93}
94
95#[derive(Debug, Clone, Deserialize)]
97pub struct ChatIdentity {
98 pub color: String,
100
101 pub badges: Vec<ChatBadge>,
103}
104
105#[derive(Debug, Clone, Deserialize)]
107pub struct ChatBadge {
108 #[serde(rename = "type")]
110 pub r#type: String,
111
112 pub text: String,
114
115 #[serde(default)]
117 pub count: Option<u32>,
118}
119
120#[cfg(test)]
121mod tests {
122 use super::*;
123
124 #[test]
125 fn test_deserialize_chat_message() {
126 let json = r##"{
127 "id": "abc-123",
128 "chatroom_id": 12345,
129 "content": "hello world",
130 "type": "message",
131 "created_at": "2025-01-01T00:00:00Z",
132 "sender": {
133 "id": 9999,
134 "username": "hello_kiko",
135 "slug": "hello_kiko",
136 "identity": {
137 "color": "#FF0000",
138 "badges": []
139 }
140 }
141 }"##;
142
143 let msg: LiveChatMessage = serde_json::from_str(json).unwrap();
144 assert_eq!(msg.id, "abc-123");
145 assert_eq!(msg.chatroom_id, Some(12345));
146 assert_eq!(msg.content, "hello world");
147 assert_eq!(msg.r#type, "message");
148 assert_eq!(msg.sender.username, "hello_kiko");
149 assert_eq!(msg.sender.id, 9999);
150 assert_eq!(msg.sender.identity.color, "#FF0000");
151 assert!(msg.sender.identity.badges.is_empty());
152 assert!(msg.metadata.is_none());
153 }
154
155 #[test]
156 fn test_deserialize_chat_message_with_badges() {
157 let json = r##"{
158 "id": "msg-456",
159 "content": "gg",
160 "type": "message",
161 "sender": {
162 "id": 1234,
163 "username": "hello_kiko",
164 "identity": {
165 "color": "#00FF00",
166 "badges": [
167 { "type": "subscriber", "text": "Subscriber", "count": 3 },
168 { "type": "moderator", "text": "Moderator" }
169 ]
170 }
171 }
172 }"##;
173
174 let msg: LiveChatMessage = serde_json::from_str(json).unwrap();
175 assert_eq!(msg.sender.identity.badges.len(), 2);
176 assert_eq!(msg.sender.identity.badges[0].r#type, "subscriber");
177 assert_eq!(msg.sender.identity.badges[0].count, Some(3));
178 assert_eq!(msg.sender.identity.badges[1].r#type, "moderator");
179 assert_eq!(msg.sender.identity.badges[1].count, None);
180 assert!(msg.chatroom_id.is_none());
182 assert!(msg.created_at.is_none());
183 assert!(msg.sender.slug.is_none());
184 }
185
186 #[test]
187 fn test_deserialize_reply_message() {
188 let json = r##"{
189 "id": "reply-789",
190 "content": "I agree!",
191 "type": "reply",
192 "sender": {
193 "id": 5555,
194 "username": "test_user",
195 "identity": {
196 "color": "#0000FF",
197 "badges": []
198 }
199 },
200 "metadata": {
201 "original_sender": { "username": "hello_kiko" },
202 "original_message": { "content": "what do you think?" }
203 }
204 }"##;
205
206 let msg: LiveChatMessage = serde_json::from_str(json).unwrap();
207 assert_eq!(msg.r#type, "reply");
208 let meta = msg.metadata.unwrap();
209 assert_eq!(meta.original_sender.unwrap().username, "hello_kiko");
210 assert_eq!(meta.original_message.unwrap().content, "what do you think?");
211 }
212
213 #[test]
214 fn test_deserialize_pusher_message() {
215 let inner_data = serde_json::json!({
218 "id": "msg-1",
219 "content": "test",
220 "type": "message",
221 "sender": {
222 "id": 1,
223 "username": "hello_kiko",
224 "identity": { "color": "#FFF", "badges": [] }
225 }
226 });
227
228 let outer = serde_json::json!({
229 "event": "App\\Events\\ChatMessageEvent",
230 "data": inner_data.to_string(),
231 "channel": "chatrooms.12345.v2"
232 });
233
234 let pusher: PusherMessage = serde_json::from_value(outer).unwrap();
235 assert!(pusher.event.contains("ChatMessageEvent"));
236 assert_eq!(pusher.channel, Some("chatrooms.12345.v2".into()));
237
238 let msg: LiveChatMessage = serde_json::from_str(&pusher.data).unwrap();
240 assert_eq!(msg.sender.username, "hello_kiko");
241 assert_eq!(msg.content, "test");
242 }
243}