//! Type definitions for IronNotify SDK. use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; /// Severity level for notifications. #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)] #[serde(rename_all = "lowercase")] pub enum SeverityLevel { #[default] Info, Success, Warning, Error, Critical, } impl std::fmt::Display for SeverityLevel { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let s = match self { Self::Info => "info", Self::Success => "success", Self::Warning => "warning", Self::Error => "error", Self::Critical => "critical", }; write!(f, "{}", s) } } /// WebSocket connection state. #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] pub enum ConnectionState { #[default] Disconnected, Connecting, Connected, Reconnecting, } impl std::fmt::Display for ConnectionState { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let s = match self { Self::Disconnected => "disconnected", Self::Connecting => "connecting", Self::Connected => "connected", Self::Reconnecting => "reconnecting", }; write!(f, "{}", s) } } /// Action button on a notification. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct NotificationAction { pub label: String, #[serde(skip_serializing_if = "Option::is_none")] pub url: Option, #[serde(skip_serializing_if = "Option::is_none")] pub action: Option, #[serde(skip_serializing_if = "Option::is_none")] pub style: Option, } impl NotificationAction { /// Creates a new action with just a label. pub fn new(label: impl Into) -> Self { Self { label: label.into(), url: None, action: None, style: Some("default".to_string()), } } /// Creates an action with a URL. pub fn with_url(label: impl Into, url: impl Into) -> Self { Self { label: label.into(), url: Some(url.into()), action: None, style: Some("default".to_string()), } } /// Creates an action with an action handler. pub fn with_handler(label: impl Into, action: impl Into) -> Self { Self { label: label.into(), url: None, action: Some(action.into()), style: Some("default".to_string()), } } /// Sets the style. pub fn style(mut self, style: impl Into) -> Self { self.style = Some(style.into()); self } } /// Payload for creating a notification. #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct NotificationPayload { pub event_type: String, pub title: String, #[serde(skip_serializing_if = "Option::is_none")] pub message: Option, #[serde(skip_serializing_if = "Option::is_none")] pub severity: Option, #[serde(skip_serializing_if = "Option::is_none")] pub metadata: Option>, #[serde(skip_serializing_if = "Option::is_none")] pub actions: Option>, #[serde(skip_serializing_if = "Option::is_none")] pub user_id: Option, #[serde(skip_serializing_if = "Option::is_none")] pub group_key: Option, #[serde(skip_serializing_if = "Option::is_none")] pub deduplication_key: Option, #[serde(skip_serializing_if = "Option::is_none")] pub expires_at: Option>, } impl NotificationPayload { /// Creates a new notification payload. pub fn new(event_type: impl Into, title: impl Into) -> Self { Self { event_type: event_type.into(), title: title.into(), message: None, severity: Some(SeverityLevel::Info), metadata: None, actions: None, user_id: None, group_key: None, deduplication_key: None, expires_at: None, } } } /// A notification received from the server. #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct Notification { pub id: String, pub event_type: String, pub title: String, #[serde(default)] pub message: Option, pub severity: SeverityLevel, #[serde(default)] pub metadata: Option>, #[serde(default)] pub actions: Option>, #[serde(default)] pub user_id: Option, #[serde(default)] pub group_key: Option, pub read: bool, pub created_at: DateTime, #[serde(default)] pub expires_at: Option>, } /// Result of sending a notification. #[derive(Debug, Clone)] pub struct SendResult { pub success: bool, pub notification_id: Option, pub error: Option, pub queued: bool, } impl SendResult { /// Creates a success result. pub fn success(notification_id: Option) -> Self { Self { success: true, notification_id, error: None, queued: false, } } /// Creates a failure result. pub fn failure(error: impl Into) -> Self { Self { success: false, notification_id: None, error: Some(error.into()), queued: false, } } /// Creates a queued result. pub fn queued(error: impl Into) -> Self { Self { success: false, notification_id: None, error: Some(error.into()), queued: true, } } }