autopush_common/db/redis/
mod.rs1mod redis_client;
15
16pub use redis_client::RedisClientImpl;
17
18use std::collections::HashMap;
19use std::time::Duration;
20
21use crate::db::error::DbError;
22use crate::notification::{default_ttl, Notification};
23use crate::util::deserialize_opt_u32_to_duration;
24
25use serde_derive::{Deserialize, Serialize};
26use uuid::Uuid;
27
28#[derive(Clone, Debug, Deserialize)]
30pub struct RedisDbSettings {
31 #[serde(default)]
32 #[serde(deserialize_with = "deserialize_opt_u32_to_duration")]
33 pub create_timeout: Option<Duration>,
34 #[serde(default)]
35 #[serde(deserialize_with = "deserialize_opt_u32_to_duration")]
36 pub router_ttl: Option<Duration>,
37 #[serde(default)]
38 #[serde(deserialize_with = "deserialize_opt_u32_to_duration")]
39 pub notification_ttl: Option<Duration>,
40}
41
42#[allow(clippy::derivable_impls)]
43impl Default for RedisDbSettings {
44 fn default() -> Self {
45 Self {
46 create_timeout: Default::default(),
47 router_ttl: Some(Duration::from_secs(crate::MAX_ROUTER_TTL_SECS)),
48 notification_ttl: Some(Duration::from_secs(crate::MAX_NOTIFICATION_TTL_SECS)),
49 }
50 }
51}
52
53impl TryFrom<&str> for RedisDbSettings {
54 type Error = DbError;
55 fn try_from(setting_string: &str) -> Result<Self, Self::Error> {
56 let me: Self = match serde_json::from_str(setting_string) {
57 Ok(me) => me,
58 Err(e) if e.is_eof() => Self::default(),
59 Err(e) => Err(DbError::General(format!(
60 "Could not parse RedisDbSettings: {:?}",
61 e
62 )))?,
63 };
64 Ok(me)
65 }
66}
67
68#[derive(Serialize, Default, Deserialize, Clone, Debug)]
69pub struct StorableNotification {
73 #[serde(rename = "channelID")]
75 pub channel_id: Uuid,
76 pub version: String,
77 pub timestamp: u64,
78 #[serde(default = "default_ttl", skip_serializing)]
80 pub ttl: u64,
81 #[serde(skip_serializing)]
83 pub topic: Option<String>,
84 #[serde(skip_serializing_if = "Option::is_none")]
85 pub data: Option<String>,
86 #[serde(skip_serializing)]
87 pub sortkey_timestamp: Option<u64>,
88 #[serde(skip_serializing_if = "Option::is_none")]
89 pub headers: Option<HashMap<String, String>>,
90 #[cfg(feature = "reliable_report")]
91 #[serde(skip_serializing_if = "Option::is_none")]
92 pub reliability_id: Option<String>,
93 #[cfg(feature = "reliable_report")]
94 #[serde(skip_serializing_if = "Option::is_none")]
95 pub reliable_state: Option<crate::reliability::ReliabilityState>,
96}
97
98impl From<Notification> for StorableNotification {
99 fn from(notification: Notification) -> Self {
100 Self {
101 channel_id: notification.channel_id,
102 version: notification.version,
103 timestamp: notification.timestamp,
104 ttl: notification.ttl,
105 topic: notification.topic,
106 data: notification.data,
107 sortkey_timestamp: notification.sortkey_timestamp,
108 headers: notification.headers,
109 #[cfg(feature = "reliable_report")]
110 reliability_id: notification.reliability_id,
111 #[cfg(feature = "reliable_report")]
112 reliable_state: notification.reliable_state,
113 }
114 }
115}
116
117impl From<StorableNotification> for Notification {
118 fn from(storable: StorableNotification) -> Self {
119 Self {
120 channel_id: storable.channel_id,
121 version: storable.version,
122 timestamp: storable.timestamp,
123 ttl: storable.ttl,
124 topic: storable.topic,
125 data: storable.data,
126 sortkey_timestamp: storable.sortkey_timestamp,
127 headers: storable.headers,
128 #[cfg(feature = "reliable_report")]
129 reliability_id: storable.reliability_id,
130 #[cfg(feature = "reliable_report")]
131 reliable_state: storable.reliable_state,
132 }
133 }
134}
135
136#[cfg(test)]
137mod tests {
138
139 #[test]
140 fn test_settings_parse() -> Result<(), crate::db::error::DbError> {
141 let settings = super::RedisDbSettings::try_from("{\"timeout\": 123}")?;
142 assert_eq!(
143 settings.create_timeout,
144 Some(std::time::Duration::from_secs(123))
145 );
146 Ok(())
147 }
148}