Skip to main content

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}
28impl EventKind {
29    /// Total number of  `EventKind`'s.
30    pub const COUNT: usize = 5;
31
32    /// Make the `EventKind` into it's u8 bit representation.
33    #[inline]
34    #[must_use]
35    pub const fn to_bit(self) -> u8 {
36        match self {
37            EventKind::IncomingMessage => 1 << 0,
38            EventKind::OutgoingMessage => 1 << 1,
39            EventKind::DeliveryReport => 1 << 2,
40            EventKind::ModemStatusUpdate => 1 << 3,
41            EventKind::GNSSPositionReport => 1 << 4,
42        }
43    }
44
45    /// Create a bitmask with all `EventKind`'s.
46    #[inline]
47    #[must_use]
48    pub const fn all_bits() -> u8 {
49        (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4)
50    }
51
52    /// Takes a set of `EventKinds` and returns its mask.
53    #[inline]
54    #[must_use]
55    pub fn events_to_mask(events: &[EventKind]) -> u8 {
56        events.iter().fold(0, |acc, event| acc | event.to_bit())
57    }
58}
59impl From<&Event> for EventKind {
60    fn from(value: &Event) -> Self {
61        match value {
62            Event::IncomingMessage(_) => EventKind::IncomingMessage,
63            Event::OutgoingMessage(_) => EventKind::OutgoingMessage,
64            Event::DeliveryReport { .. } => EventKind::DeliveryReport,
65            Event::ModemStatusUpdate { .. } => EventKind::ModemStatusUpdate,
66
67            #[cfg(feature = "gnss")]
68            Event::GnssPositionReport(_) => EventKind::GNSSPositionReport,
69        }
70    }
71}
72impl TryFrom<&str> for EventKind {
73    type Error = String;
74
75    /// Convert a str into an `EventKind`.
76    #[inline]
77    fn try_from(value: &str) -> Result<Self, Self::Error> {
78        match value {
79            "incoming" => Ok(EventKind::IncomingMessage),
80            "outgoing" => Ok(EventKind::OutgoingMessage),
81            "delivery" => Ok(EventKind::DeliveryReport),
82            "modem_status_update" => Ok(EventKind::ModemStatusUpdate),
83            "gnss_position_report" => Ok(EventKind::GNSSPositionReport),
84            _ => Err(format!("Unknown event type {value}")),
85        }
86    }
87}
88
89/// Event types that can be sent by the server.
90#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
91#[serde(tag = "type", content = "data")]
92pub enum Event {
93    /// New SMS message received.
94    #[serde(rename = "incoming")]
95    IncomingMessage(crate::sms::SmsMessage),
96
97    /// SMS message being sent from API or other connected client.
98    #[serde(rename = "outgoing")]
99    OutgoingMessage(crate::sms::SmsMessage),
100
101    /// Delivery report update.
102    #[serde(rename = "delivery")]
103    DeliveryReport {
104        /// The target `message_id` this delivery report applies to.
105        /// This is determined from the `message_reference` and sender.
106        message_id: i64,
107
108        /// The received delivery report.
109        report: crate::sms::SmsPartialDeliveryReport,
110    },
111
112    /// Modem hat connection status update.
113    /// This can be either: Startup, Online, `ShuttingDown`, Offline
114    #[serde(rename = "modem_status_update")]
115    ModemStatusUpdate {
116        /// Previous state from last update.
117        previous: crate::modem::ModemStatusUpdateState,
118
119        /// Current state after update.
120        current: crate::modem::ModemStatusUpdateState,
121    },
122
123    /// An unsolicited position report from GNSS.
124    #[cfg(feature = "gnss")]
125    #[serde(rename = "gnss_position_report")]
126    GnssPositionReport(crate::gnss::PositionReport),
127}