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
93impl Default for Config {
94 fn default() -> Self {
95 Self {
96 token: String::new(),
97 mode: NetworkMode::Native,
98 client: None,
99 fetch: None,
100 web_socket_factory: None,
101 ping_interval: 15.0,
102 pong_timeout: 14.0,
103 reconnect_backoff_max: 32.0,
104 max_reconnect_attempts: 10,
105 }
106 }
107}
108
109#[derive(Debug, Clone, Serialize, Deserialize)]
111pub struct DeviceRegistration {
112 #[serde(rename = "webSocketUrl")]
114 pub web_socket_url: String,
115
116 #[serde(rename = "url")]
118 pub device_url: String,
119
120 #[serde(rename = "userId")]
122 pub user_id: String,
123
124 #[serde(default)]
126 pub services: HashMap<String, String>,
127
128 #[serde(skip)]
130 pub encryption_service_url: String,
131}
132
133#[derive(Debug, Clone, Default, Serialize, Deserialize)]
135pub struct MercuryActor {
136 #[serde(default)]
137 pub id: String,
138
139 #[serde(rename = "objectType", default)]
140 pub object_type: String,
141
142 #[serde(rename = "emailAddress", default)]
143 pub email_address: Option<String>,
144}
145
146#[derive(Debug, Clone, Default, Serialize, Deserialize)]
148pub struct MercuryObject {
149 #[serde(default)]
150 pub id: String,
151
152 #[serde(rename = "objectType", default)]
153 pub object_type: String,
154
155 #[serde(rename = "displayName", default)]
156 pub display_name: Option<String>,
157
158 #[serde(default)]
159 pub content: Option<String>,
160
161 #[serde(rename = "encryptionKeyUrl", default)]
162 pub encryption_key_url: Option<String>,
163}
164
165#[derive(Debug, Clone, Default, Serialize, Deserialize)]
167pub struct MercuryTarget {
168 #[serde(default)]
169 pub id: String,
170
171 #[serde(rename = "objectType", default)]
172 pub object_type: String,
173
174 #[serde(rename = "encryptionKeyUrl", default)]
175 pub encryption_key_url: Option<String>,
176
177 #[serde(default)]
178 pub tags: Vec<String>,
179}
180
181#[derive(Debug, Clone, Serialize, Deserialize)]
183pub struct MercuryActivity {
184 #[serde(default)]
185 pub id: String,
186
187 #[serde(default)]
188 pub verb: String,
189
190 #[serde(default)]
191 pub actor: MercuryActor,
192
193 #[serde(default)]
194 pub object: MercuryObject,
195
196 #[serde(default)]
197 pub target: MercuryTarget,
198
199 #[serde(default)]
200 pub published: String,
201
202 #[serde(rename = "encryptionKeyUrl", default)]
203 pub encryption_key_url: Option<String>,
204}
205
206#[derive(Debug, Clone)]
208pub struct DecryptedMessage {
209 pub id: String,
211
212 pub room_id: String,
214
215 pub person_id: String,
217
218 pub person_email: String,
220
221 pub text: String,
223
224 pub html: Option<String>,
226
227 pub created: String,
229
230 pub room_type: Option<String>,
232
233 pub raw: MercuryActivity,
235}
236
237#[derive(Debug, Clone)]
239pub struct DeletedMessage {
240 pub message_id: String,
241 pub room_id: String,
242 pub person_id: String,
243}
244
245#[derive(Debug, Clone, Copy, PartialEq, Eq)]
247pub enum ConnectionStatus {
248 Connected,
249 Connecting,
250 Reconnecting,
251 Disconnected,
252}
253
254impl std::fmt::Display for ConnectionStatus {
255 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
256 match self {
257 Self::Connected => write!(f, "connected"),
258 Self::Connecting => write!(f, "connecting"),
259 Self::Reconnecting => write!(f, "reconnecting"),
260 Self::Disconnected => write!(f, "disconnected"),
261 }
262 }
263}
264
265#[derive(Debug, Clone)]
267pub struct HandlerStatus {
268 pub status: ConnectionStatus,
270
271 pub web_socket_open: bool,
273
274 pub kms_initialized: bool,
276
277 pub device_registered: bool,
279
280 pub reconnect_attempt: u32,
282}