1use serde::{Deserialize, Serialize};
4use std::collections::HashMap;
5use std::future::Future;
6use std::pin::Pin;
7use std::sync::Arc;
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub enum NetworkMode {
12 Native,
14 Injected,
16}
17
18impl Default for NetworkMode {
19 fn default() -> Self {
20 Self::Native
21 }
22}
23
24#[derive(Debug, Clone)]
26pub struct FetchRequest {
27 pub url: String,
28 pub method: String,
29 pub headers: HashMap<String, String>,
30 pub body: Option<String>,
31}
32
33pub struct FetchResponse {
35 pub status: u16,
36 pub ok: bool,
37 pub body: Vec<u8>,
38}
39
40pub type FetchFn = Arc<
42 dyn Fn(FetchRequest) -> Pin<Box<dyn Future<Output = Result<FetchResponse, Box<dyn std::error::Error + Send + Sync>>> + Send>>
43 + Send
44 + Sync,
45>;
46
47pub trait InjectedWebSocket: Send + Sync {
49 fn send(&self, data: String) -> Pin<Box<dyn Future<Output = Result<(), Box<dyn std::error::Error + Send + Sync>>> + Send + '_>>;
50 fn receive(&self) -> Pin<Box<dyn Future<Output = Result<String, Box<dyn std::error::Error + Send + Sync>>> + Send + '_>>;
51 fn close(&self) -> Pin<Box<dyn Future<Output = Result<(), Box<dyn std::error::Error + Send + Sync>>> + Send + '_>>;
52}
53
54pub type WebSocketFactory = Arc<
56 dyn Fn(String) -> Pin<Box<dyn Future<Output = Result<Box<dyn InjectedWebSocket>, Box<dyn std::error::Error + Send + Sync>>> + Send>>
57 + Send
58 + Sync,
59>;
60
61#[derive(Clone)]
63pub struct Config {
64 pub token: String,
66
67 pub mode: NetworkMode,
69
70 pub client: Option<reqwest::Client>,
73
74 pub fetch: Option<FetchFn>,
76
77 pub web_socket_factory: Option<WebSocketFactory>,
79
80 pub ping_interval: f64,
82
83 pub pong_timeout: f64,
85
86 pub reconnect_backoff_max: f64,
88
89 pub max_reconnect_attempts: u32,
91
92 pub ignore_self_messages: bool,
94}
95
96impl Default for Config {
97 fn default() -> Self {
98 Self {
99 token: String::new(),
100 mode: NetworkMode::Native,
101 client: None,
102 fetch: None,
103 web_socket_factory: None,
104 ping_interval: 15.0,
105 pong_timeout: 14.0,
106 reconnect_backoff_max: 32.0,
107 max_reconnect_attempts: 10,
108 ignore_self_messages: true,
109 }
110 }
111}
112
113#[derive(Debug, Clone, Serialize, Deserialize)]
115pub struct DeviceRegistration {
116 #[serde(rename = "webSocketUrl")]
118 pub web_socket_url: String,
119
120 #[serde(rename = "url")]
122 pub device_url: String,
123
124 #[serde(rename = "userId")]
126 pub user_id: String,
127
128 #[serde(default)]
130 pub services: HashMap<String, String>,
131
132 #[serde(skip)]
134 pub encryption_service_url: String,
135}
136
137#[derive(Debug, Clone, Default, Serialize, Deserialize)]
139pub struct MercuryActor {
140 #[serde(default)]
141 pub id: String,
142
143 #[serde(rename = "objectType", default)]
144 pub object_type: String,
145
146 #[serde(rename = "emailAddress", default)]
147 pub email_address: Option<String>,
148}
149
150#[derive(Debug, Clone, Default, Serialize, Deserialize)]
152pub struct MercuryObject {
153 #[serde(default)]
154 pub id: String,
155
156 #[serde(rename = "objectType", default)]
157 pub object_type: String,
158
159 #[serde(rename = "displayName", default)]
160 pub display_name: Option<String>,
161
162 #[serde(default)]
163 pub content: Option<String>,
164
165 #[serde(rename = "encryptionKeyUrl", default)]
166 pub encryption_key_url: Option<String>,
167}
168
169#[derive(Debug, Clone, Default, Serialize, Deserialize)]
171pub struct MercuryTarget {
172 #[serde(default)]
173 pub id: String,
174
175 #[serde(rename = "objectType", default)]
176 pub object_type: String,
177
178 #[serde(rename = "encryptionKeyUrl", default)]
179 pub encryption_key_url: Option<String>,
180
181 #[serde(default)]
182 pub tags: Vec<String>,
183}
184
185#[derive(Debug, Clone, Serialize, Deserialize)]
187pub struct MercuryActivity {
188 #[serde(default)]
189 pub id: String,
190
191 #[serde(default)]
192 pub verb: String,
193
194 #[serde(default)]
195 pub actor: MercuryActor,
196
197 #[serde(default)]
198 pub object: MercuryObject,
199
200 #[serde(default)]
201 pub target: MercuryTarget,
202
203 #[serde(default)]
204 pub published: String,
205
206 #[serde(rename = "encryptionKeyUrl", default)]
207 pub encryption_key_url: Option<String>,
208}
209
210#[derive(Debug, Clone)]
212pub struct DecryptedMessage {
213 pub id: String,
215
216 pub room_id: String,
218
219 pub person_id: String,
221
222 pub person_email: String,
224
225 pub text: String,
227
228 pub html: Option<String>,
230
231 pub created: String,
233
234 pub room_type: Option<String>,
236
237 pub raw: MercuryActivity,
239}
240
241#[derive(Debug, Clone)]
243pub struct DeletedMessage {
244 pub message_id: String,
245 pub room_id: String,
246 pub person_id: String,
247}
248
249#[derive(Debug, Clone, Copy, PartialEq, Eq)]
251pub enum ConnectionStatus {
252 Connected,
253 Connecting,
254 Reconnecting,
255 Disconnected,
256}
257
258impl std::fmt::Display for ConnectionStatus {
259 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
260 match self {
261 Self::Connected => write!(f, "connected"),
262 Self::Connecting => write!(f, "connecting"),
263 Self::Reconnecting => write!(f, "reconnecting"),
264 Self::Disconnected => write!(f, "disconnected"),
265 }
266 }
267}
268
269#[derive(Debug, Clone)]
271pub struct HandlerStatus {
272 pub status: ConnectionStatus,
274
275 pub web_socket_open: bool,
277
278 pub kms_initialized: bool,
280
281 pub device_registered: bool,
283
284 pub reconnect_attempt: u32,
286}