use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::future::Future;
use std::pin::Pin;
use std::sync::Arc;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum NetworkMode {
#[default]
Native,
Injected,
}
#[derive(Debug, Clone)]
pub struct FetchRequest {
pub url: String,
pub method: String,
pub headers: HashMap<String, String>,
pub body: Option<String>,
}
pub struct FetchResponse {
pub status: u16,
pub ok: bool,
pub body: Vec<u8>,
}
pub type FetchFn = Arc<
dyn Fn(FetchRequest) -> Pin<Box<dyn Future<Output = Result<FetchResponse, Box<dyn std::error::Error + Send + Sync>>> + Send>>
+ Send
+ Sync,
>;
type BoxFutureResult<'a, T> = Pin<Box<dyn Future<Output = Result<T, Box<dyn std::error::Error + Send + Sync>>> + Send + 'a>>;
pub trait InjectedWebSocket: Send + Sync {
fn send(&self, data: String) -> BoxFutureResult<'_, ()>;
fn receive(&self) -> BoxFutureResult<'_, String>;
fn close(&self) -> BoxFutureResult<'_, ()>;
}
pub type WebSocketFactory = Arc<
dyn Fn(String) -> Pin<Box<dyn Future<Output = Result<Box<dyn InjectedWebSocket>, Box<dyn std::error::Error + Send + Sync>>> + Send>>
+ Send
+ Sync,
>;
#[derive(Clone)]
pub struct Config {
pub token: String,
pub mode: NetworkMode,
pub client: Option<reqwest::Client>,
pub fetch: Option<FetchFn>,
pub web_socket_factory: Option<WebSocketFactory>,
pub ping_interval: f64,
pub pong_timeout: f64,
pub reconnect_backoff_max: f64,
pub max_reconnect_attempts: u32,
pub ignore_self_messages: bool,
}
impl Default for Config {
fn default() -> Self {
Self {
token: String::new(),
mode: NetworkMode::Native,
client: None,
fetch: None,
web_socket_factory: None,
ping_interval: 15.0,
pong_timeout: 14.0,
reconnect_backoff_max: 32.0,
max_reconnect_attempts: 10,
ignore_self_messages: true,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DeviceRegistration {
#[serde(rename = "webSocketUrl")]
pub web_socket_url: String,
#[serde(rename = "url")]
pub device_url: String,
#[serde(rename = "userId")]
pub user_id: String,
#[serde(default)]
pub services: HashMap<String, String>,
#[serde(skip)]
pub encryption_service_url: String,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct MercuryActor {
#[serde(default)]
pub id: String,
#[serde(rename = "objectType", default)]
pub object_type: String,
#[serde(rename = "emailAddress", default)]
pub email_address: Option<String>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct MercuryObject {
#[serde(default)]
pub id: String,
#[serde(rename = "objectType", default)]
pub object_type: String,
#[serde(rename = "displayName", default)]
pub display_name: Option<String>,
#[serde(default)]
pub content: Option<String>,
#[serde(rename = "encryptionKeyUrl", default)]
pub encryption_key_url: Option<String>,
#[serde(default)]
pub inputs: Option<serde_json::Value>,
#[serde(default)]
pub files: Option<Vec<String>>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct MercuryTarget {
#[serde(default)]
pub id: String,
#[serde(rename = "objectType", default)]
pub object_type: String,
#[serde(rename = "encryptionKeyUrl", default)]
pub encryption_key_url: Option<String>,
#[serde(default)]
pub tags: Vec<String>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct MercuryParent {
#[serde(default)]
pub id: String,
#[serde(rename = "type", default)]
pub parent_type: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MercuryActivity {
#[serde(default)]
pub id: String,
#[serde(default)]
pub verb: String,
#[serde(default)]
pub actor: MercuryActor,
#[serde(default)]
pub object: MercuryObject,
#[serde(default)]
pub target: MercuryTarget,
#[serde(default)]
pub published: String,
#[serde(rename = "encryptionKeyUrl", default)]
pub encryption_key_url: Option<String>,
#[serde(default)]
pub parent: Option<MercuryParent>,
}
#[derive(Debug, Clone)]
pub struct DecryptedMessage {
pub id: String,
pub parent_id: Option<String>,
pub mentioned_people: Vec<String>,
pub mentioned_groups: Vec<String>,
pub room_id: String,
pub person_id: String,
pub person_email: String,
pub text: String,
pub html: Option<String>,
pub created: String,
pub room_type: Option<String>,
pub files: Vec<String>,
pub raw: MercuryActivity,
}
#[derive(Debug, Clone)]
pub struct DeletedMessage {
pub message_id: String,
pub room_id: String,
pub person_id: String,
}
#[derive(Debug, Clone)]
pub struct MembershipActivity {
pub id: String,
pub actor_id: String,
pub person_id: String,
pub room_id: String,
pub action: String,
pub created: String,
pub room_type: Option<String>,
pub raw: MercuryActivity,
}
#[derive(Debug, Clone)]
pub struct AttachmentAction {
pub id: String,
pub message_id: String,
pub person_id: String,
pub person_email: String,
pub room_id: String,
pub inputs: serde_json::Value,
pub created: String,
pub raw: MercuryActivity,
}
#[derive(Debug, Clone)]
pub struct RoomActivity {
pub id: String,
pub room_id: String,
pub actor_id: String,
pub action: String,
pub created: String,
pub raw: MercuryActivity,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ConnectionStatus {
Connected,
Connecting,
Reconnecting,
Disconnected,
}
impl std::fmt::Display for ConnectionStatus {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Connected => write!(f, "connected"),
Self::Connecting => write!(f, "connecting"),
Self::Reconnecting => write!(f, "reconnecting"),
Self::Disconnected => write!(f, "disconnected"),
}
}
}
#[derive(Debug, Clone)]
pub struct HandlerStatus {
pub status: ConnectionStatus,
pub web_socket_open: bool,
pub kms_initialized: bool,
pub device_registered: bool,
pub reconnect_attempt: u32,
}