sms_types/
events.rs

1//! Events that are sent via webhook or websocket.
2
3use serde::{Deserialize, Serialize};
4
5/// The Kind of Event.
6#[derive(Eq, PartialEq, Hash, Debug, Clone, Copy, Deserialize)]
7pub enum EventKind {
8    /// New SMS message received.
9    #[serde(rename = "incoming")]
10    IncomingMessage,
11
12    /// SMS message being sent from API or other connected client.
13    #[serde(rename = "outgoing")]
14    OutgoingMessage,
15
16    /// Delivery report update.
17    #[serde(rename = "delivery")]
18    DeliveryReport,
19
20    /// Modem hat connection status update.
21    #[serde(rename = "modem_status_update")]
22    ModemStatusUpdate,
23
24    /// An unsolicited position report from GNSS.
25    #[serde(rename = "gnss_position_report")]
26    GNSSPositionReport,
27
28    /// WebSocket connection status update (client-side only).
29    #[serde(rename = "websocket_connection_update")]
30    WebsocketConnectionUpdate,
31}
32impl EventKind {
33    /// Total number of `EventKind`'s.
34    pub const COUNT: usize = 6;
35
36    /// Make the `EventKind` into it's u8 bit representation.
37    #[inline]
38    #[must_use]
39    pub const fn to_bit(self) -> u8 {
40        match self {
41            EventKind::IncomingMessage => 1 << 0,
42            EventKind::OutgoingMessage => 1 << 1,
43            EventKind::DeliveryReport => 1 << 2,
44            EventKind::ModemStatusUpdate => 1 << 3,
45            EventKind::GNSSPositionReport => 1 << 4,
46            EventKind::WebsocketConnectionUpdate => 1 << 5,
47        }
48    }
49
50    /// Create a bitmask with all server `EventKind`'s.
51    #[inline]
52    #[must_use]
53    pub const fn all_bits() -> u8 {
54        (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4)
55    }
56
57    /// Takes a set of `EventKinds` and returns its mask.
58    #[inline]
59    #[must_use]
60    pub fn events_to_mask(events: &[EventKind]) -> u8 {
61        events.iter().fold(0, |acc, event| acc | event.to_bit())
62    }
63}
64impl From<&Event> for EventKind {
65    fn from(value: &Event) -> Self {
66        match value {
67            Event::IncomingMessage(_) => EventKind::IncomingMessage,
68            Event::OutgoingMessage(_) => EventKind::OutgoingMessage,
69            Event::DeliveryReport { .. } => EventKind::DeliveryReport,
70            Event::ModemStatusUpdate { .. } => EventKind::ModemStatusUpdate,
71            Event::WebsocketConnectionUpdate { .. } => EventKind::WebsocketConnectionUpdate,
72
73            #[cfg(feature = "gnss")]
74            Event::GnssPositionReport(_) => EventKind::GNSSPositionReport,
75        }
76    }
77}
78impl TryFrom<&str> for EventKind {
79    type Error = String;
80
81    /// Convert a str into an `EventKind`.
82    #[inline]
83    fn try_from(value: &str) -> Result<Self, Self::Error> {
84        match value {
85            "incoming" => Ok(EventKind::IncomingMessage),
86            "outgoing" => Ok(EventKind::OutgoingMessage),
87            "delivery" => Ok(EventKind::DeliveryReport),
88            "modem_status_update" => Ok(EventKind::ModemStatusUpdate),
89            "websocket_connection_upgrade" => Ok(EventKind::WebsocketConnectionUpdate),
90            "gnss_position_report" => Ok(EventKind::GNSSPositionReport),
91            _ => Err(format!("Unknown event type {value}")),
92        }
93    }
94}
95
96/// Event types that can be sent by the server.
97#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
98#[serde(tag = "type", content = "data")]
99pub enum Event {
100    /// New SMS message received.
101    #[serde(rename = "incoming")]
102    IncomingMessage(crate::sms::SmsMessage),
103
104    /// SMS message being sent from API or other connected client.
105    #[serde(rename = "outgoing")]
106    OutgoingMessage(crate::sms::SmsMessage),
107
108    /// Delivery report update.
109    #[serde(rename = "delivery")]
110    DeliveryReport {
111        /// The target `message_id` this delivery report applies to.
112        /// This is determined from the `message_reference` and sender.
113        message_id: i64,
114
115        /// The received delivery report.
116        report: crate::sms::SmsPartialDeliveryReport,
117    },
118
119    /// Modem hat connection status update.
120    /// This can be either: Startup, Online, `ShuttingDown`, Offline
121    #[serde(rename = "modem_status_update")]
122    ModemStatusUpdate {
123        /// Previous state from last update.
124        previous: crate::modem::ModemStatusUpdateState,
125
126        /// Current state after update.
127        current: crate::modem::ModemStatusUpdateState,
128    },
129
130    /// WebSocket connection status update (client-side only).
131    /// This message is generated locally when there is a connection or disconnection.
132    WebsocketConnectionUpdate {
133        /// Connection status: true = connected, false = disconnected
134        connected: bool,
135
136        /// If connection is false, will the client attempt to automatically reconnect?
137        reconnect: bool,
138    },
139
140    /// An unsolicited position report from GNSS.
141    #[cfg(feature = "gnss")]
142    #[serde(rename = "gnss_position_report")]
143    GnssPositionReport(crate::gnss::PositionReport),
144}