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, Default)]
11pub enum NetworkMode {
12 #[default]
14 Native,
15 Injected,
17}
18
19#[derive(Debug, Clone)]
21pub struct FetchRequest {
22 pub url: String,
23 pub method: String,
24 pub headers: HashMap<String, String>,
25 pub body: Option<String>,
26}
27
28pub struct FetchResponse {
30 pub status: u16,
31 pub ok: bool,
32 pub body: Vec<u8>,
33}
34
35pub type FetchFn = Arc<
37 dyn Fn(FetchRequest) -> Pin<Box<dyn Future<Output = Result<FetchResponse, Box<dyn std::error::Error + Send + Sync>>> + Send>>
38 + Send
39 + Sync,
40>;
41
42type BoxFutureResult<'a, T> = Pin<Box<dyn Future<Output = Result<T, Box<dyn std::error::Error + Send + Sync>>> + Send + 'a>>;
44
45pub trait InjectedWebSocket: Send + Sync {
47 fn send(&self, data: String) -> BoxFutureResult<'_, ()>;
48 fn receive(&self) -> BoxFutureResult<'_, String>;
49 fn close(&self) -> BoxFutureResult<'_, ()>;
50}
51
52pub type WebSocketFactory = Arc<
54 dyn Fn(String) -> Pin<Box<dyn Future<Output = Result<Box<dyn InjectedWebSocket>, Box<dyn std::error::Error + Send + Sync>>> + Send>>
55 + Send
56 + Sync,
57>;
58
59#[derive(Clone)]
61pub struct Config {
62 pub token: String,
64
65 pub mode: NetworkMode,
67
68 pub client: Option<reqwest::Client>,
71
72 pub fetch: Option<FetchFn>,
74
75 pub web_socket_factory: Option<WebSocketFactory>,
77
78 pub ping_interval: f64,
80
81 pub pong_timeout: f64,
83
84 pub reconnect_backoff_max: f64,
86
87 pub max_reconnect_attempts: u32,
89
90 pub ignore_self_messages: bool,
92}
93
94impl Default for Config {
95 fn default() -> Self {
96 Self {
97 token: String::new(),
98 mode: NetworkMode::Native,
99 client: None,
100 fetch: None,
101 web_socket_factory: None,
102 ping_interval: 15.0,
103 pong_timeout: 14.0,
104 reconnect_backoff_max: 32.0,
105 max_reconnect_attempts: 10,
106 ignore_self_messages: true,
107 }
108 }
109}
110
111#[derive(Debug, Clone, Serialize, Deserialize)]
113pub struct DeviceRegistration {
114 #[serde(rename = "webSocketUrl")]
116 pub web_socket_url: String,
117
118 #[serde(rename = "url")]
120 pub device_url: String,
121
122 #[serde(rename = "userId")]
124 pub user_id: String,
125
126 #[serde(default)]
128 pub services: HashMap<String, String>,
129
130 #[serde(skip)]
132 pub encryption_service_url: String,
133}
134
135#[derive(Debug, Clone, Default, Serialize, Deserialize)]
137pub struct MercuryActor {
138 #[serde(default)]
139 pub id: String,
140
141 #[serde(rename = "objectType", default)]
142 pub object_type: String,
143
144 #[serde(rename = "emailAddress", default)]
145 pub email_address: Option<String>,
146}
147
148#[derive(Debug, Clone, Default, Serialize, Deserialize)]
150pub struct MercuryObject {
151 #[serde(default)]
152 pub id: String,
153
154 #[serde(rename = "objectType", default)]
155 pub object_type: String,
156
157 #[serde(rename = "displayName", default)]
158 pub display_name: Option<String>,
159
160 #[serde(default)]
161 pub content: Option<String>,
162
163 #[serde(rename = "encryptionKeyUrl", default)]
164 pub encryption_key_url: Option<String>,
165}
166
167#[derive(Debug, Clone, Default, Serialize, Deserialize)]
169pub struct MercuryTarget {
170 #[serde(default)]
171 pub id: String,
172
173 #[serde(rename = "objectType", default)]
174 pub object_type: String,
175
176 #[serde(rename = "encryptionKeyUrl", default)]
177 pub encryption_key_url: Option<String>,
178
179 #[serde(default)]
180 pub tags: Vec<String>,
181}
182
183#[derive(Debug, Clone, Serialize, Deserialize)]
185pub struct MercuryActivity {
186 #[serde(default)]
187 pub id: String,
188
189 #[serde(default)]
190 pub verb: String,
191
192 #[serde(default)]
193 pub actor: MercuryActor,
194
195 #[serde(default)]
196 pub object: MercuryObject,
197
198 #[serde(default)]
199 pub target: MercuryTarget,
200
201 #[serde(default)]
202 pub published: String,
203
204 #[serde(rename = "encryptionKeyUrl", default)]
205 pub encryption_key_url: Option<String>,
206}
207
208#[derive(Debug, Clone)]
210pub struct DecryptedMessage {
211 pub id: String,
213
214 pub room_id: String,
216
217 pub person_id: String,
219
220 pub person_email: String,
222
223 pub text: String,
225
226 pub html: Option<String>,
228
229 pub created: String,
231
232 pub room_type: Option<String>,
234
235 pub raw: MercuryActivity,
237}
238
239#[derive(Debug, Clone)]
241pub struct DeletedMessage {
242 pub message_id: String,
243 pub room_id: String,
244 pub person_id: String,
245}
246
247#[derive(Debug, Clone)]
249pub struct MembershipActivity {
250 pub id: String,
252
253 pub actor_id: String,
255
256 pub person_id: String,
258
259 pub room_id: String,
261
262 pub action: String,
264
265 pub created: String,
267
268 pub room_type: Option<String>,
270
271 pub raw: MercuryActivity,
273}
274
275#[derive(Debug, Clone, Copy, PartialEq, Eq)]
277pub enum ConnectionStatus {
278 Connected,
279 Connecting,
280 Reconnecting,
281 Disconnected,
282}
283
284impl std::fmt::Display for ConnectionStatus {
285 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
286 match self {
287 Self::Connected => write!(f, "connected"),
288 Self::Connecting => write!(f, "connecting"),
289 Self::Reconnecting => write!(f, "reconnecting"),
290 Self::Disconnected => write!(f, "disconnected"),
291 }
292 }
293}
294
295#[derive(Debug, Clone)]
297pub struct HandlerStatus {
298 pub status: ConnectionStatus,
300
301 pub web_socket_open: bool,
303
304 pub kms_initialized: bool,
306
307 pub device_registered: bool,
309
310 pub reconnect_attempt: u32,
312}