Skip to main content

rust_mqtt/types/
qos.rs

1use crate::types::PacketIdentifier;
2
3/// MQTT's Quality of Service
4#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Ord)]
5#[cfg_attr(feature = "defmt", derive(defmt::Format))]
6pub enum QoS {
7    /// Quality of Service Level 0. Publications with this level are only sent once.
8    AtMostOnce = 0,
9    /// Quality of Service Level 1. Publications with this level are sent until a PUBACK indicates that it was received.
10    AtLeastOnce = 1,
11    /// Quality of Service Level 2. Publications with this level are followed by a handshake assuring it is received once.
12    ExactlyOnce = 2,
13}
14impl From<IdentifiedQoS> for QoS {
15    fn from(value: IdentifiedQoS) -> Self {
16        match value {
17            IdentifiedQoS::AtMostOnce => Self::AtMostOnce,
18            IdentifiedQoS::AtLeastOnce(_) => Self::AtLeastOnce,
19            IdentifiedQoS::ExactlyOnce(_) => Self::ExactlyOnce,
20        }
21    }
22}
23
24impl QoS {
25    pub(crate) const fn into_bits(self, left_shift: u8) -> u8 {
26        let bits = match self {
27            Self::AtMostOnce => 0x00,
28            Self::AtLeastOnce => 0x01,
29            Self::ExactlyOnce => 0x02,
30        };
31
32        bits << left_shift
33    }
34
35    pub(crate) const fn try_from_bits(bits: u8) -> Option<Self> {
36        match bits {
37            0x00 => Some(Self::AtMostOnce),
38            0x01 => Some(Self::AtLeastOnce),
39            0x02 => Some(Self::ExactlyOnce),
40            _ => None,
41        }
42    }
43}
44
45/// MQTT's Quality of Service with special reference to the PUBLISH packet which contains
46/// a packet identifier if its Quality of Service is greater than 0.
47#[derive(Debug, Clone, Copy, PartialEq, Eq)]
48#[cfg_attr(feature = "defmt", derive(defmt::Format))]
49pub enum IdentifiedQoS {
50    /// Quality of Service Level 0. PUBLISH packets do not contain a packet identifier.
51    AtMostOnce,
52    /// Quality of Service Level 1. PUBLISH packets contain the included packet identifier.
53    AtLeastOnce(PacketIdentifier),
54    /// Quality of Service Level 2. PUBLISH packets contain the included packet identifier.
55    ExactlyOnce(PacketIdentifier),
56}
57
58impl IdentifiedQoS {
59    /// Returns [`Some`] if [`QoS`] > 0 and therefore has to be identified, and
60    /// [`None`] otherwise.
61    #[inline]
62    #[must_use]
63    pub const fn packet_identifier(&self) -> Option<PacketIdentifier> {
64        match self {
65            Self::AtMostOnce => None,
66            Self::AtLeastOnce(pid) | Self::ExactlyOnce(pid) => Some(*pid),
67        }
68    }
69}