ferro_notifications/channels/
database.rs1use serde::{Deserialize, Serialize};
4use serde_json::Value;
5use std::collections::HashMap;
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
12pub struct DatabaseMessage {
13 pub notification_type: String,
15 pub data: HashMap<String, Value>,
17}
18
19impl DatabaseMessage {
20 pub fn new(notification_type: impl Into<String>) -> Self {
22 Self {
23 notification_type: notification_type.into(),
24 data: HashMap::new(),
25 }
26 }
27
28 pub fn data<V: Serialize>(mut self, key: impl Into<String>, value: V) -> Self {
30 if let Ok(v) = serde_json::to_value(value) {
31 self.data.insert(key.into(), v);
32 }
33 self
34 }
35
36 pub fn with_data(mut self, data: HashMap<String, Value>) -> Self {
38 self.data.extend(data);
39 self
40 }
41
42 pub fn get(&self, key: &str) -> Option<&Value> {
44 self.data.get(key)
45 }
46
47 pub fn to_json(&self) -> Result<String, serde_json::Error> {
49 serde_json::to_string(self)
50 }
51}
52
53#[cfg(test)]
54mod tests {
55 use super::*;
56
57 #[test]
58 fn test_database_message_builder() {
59 let msg = DatabaseMessage::new("order_shipped")
60 .data("order_id", 123)
61 .data("tracking", "ABC123");
62
63 assert_eq!(msg.notification_type, "order_shipped");
64 assert_eq!(msg.get("order_id"), Some(&Value::Number(123.into())));
65 assert_eq!(msg.get("tracking"), Some(&Value::String("ABC123".into())));
66 }
67
68 #[test]
69 fn test_database_message_to_json() {
70 let msg = DatabaseMessage::new("test").data("key", "value");
71
72 let json = msg.to_json().unwrap();
73 assert!(json.contains("\"notification_type\":\"test\""));
74 assert!(json.contains("\"key\":\"value\""));
75 }
76}