mqtt_protocol_core/mqtt/packet/qos.rs
1// MIT License
2//
3// Copyright (c) 2025 Takatoshi Kondo
4//
5// Permission is hereby granted, free of charge, to any person obtaining a copy
6// of this software and associated documentation files (the "Software"), to deal
7// in the Software without restriction, including without limitation the rights
8// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9// copies of the Software, and to permit persons to whom the Software is
10// furnished to do so, subject to the following conditions:
11//
12// The above copyright notice and this permission notice shall be included in all
13// copies or substantial portions of the Software.
14//
15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21// SOFTWARE.
22
23use core::fmt;
24use num_enum::TryFromPrimitive;
25use serde::{Deserialize, Serialize};
26
27/// MQTT Quality of Service levels
28///
29/// Defines the delivery guarantee levels for MQTT message publishing and subscription.
30/// Each QoS level provides different guarantees about message delivery, with higher
31/// levels providing stronger guarantees at the cost of increased overhead.
32///
33/// The QoS level is specified in PUBLISH packets and affects how the message is
34/// handled by both the sender and receiver according to the MQTT protocol specification.
35///
36/// # QoS Level Descriptions
37///
38/// - **QoS 0 (At Most Once)**: Fire-and-forget delivery. Messages are delivered
39/// at most once, or not at all. No acknowledgment is required.
40/// - **QoS 1 (At Least Once)**: Acknowledged delivery. Messages are delivered
41/// at least once. Duplicates may occur but will be handled by the receiver.
42/// - **QoS 2 (Exactly Once)**: Assured delivery. Messages are delivered exactly
43/// once using a four-part handshake protocol.
44///
45/// # Protocol Behavior
46///
47/// Each QoS level has specific protocol requirements:
48///
49/// - **QoS 0**: PUBLISH packet is sent without expecting acknowledgment
50/// - **QoS 1**: PUBLISH packet must be acknowledged with PUBACK
51/// - **QoS 2**: PUBLISH packet initiates a handshake: PUBLISH -> PUBREC -> PUBREL -> PUBCOMP
52///
53/// # Examples
54///
55/// ```ignore
56/// use mqtt_protocol_core::mqtt;
57///
58/// // Fire-and-forget message delivery
59/// let qos0 = mqtt::packet::Qos::AtMostOnce;
60///
61/// // Acknowledged delivery with possible duplicates
62/// let qos1 = mqtt::packet::Qos::AtLeastOnce;
63///
64/// // Exactly-once delivery with handshake
65/// let qos2 = mqtt::packet::Qos::ExactlyOnce;
66///
67/// // Convert from byte value
68/// let qos_from_byte = mqtt::packet::Qos::try_from(1u8).unwrap();
69/// assert_eq!(qos_from_byte, mqtt::packet::Qos::AtLeastOnce);
70/// ```
71#[derive(
72 Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, TryFromPrimitive,
73)]
74#[cfg_attr(feature = "defmt", derive(defmt::Format))]
75#[repr(u8)]
76pub enum Qos {
77 /// QoS level 0: At most once delivery
78 ///
79 /// Messages are delivered at most once, or not at all. There is no
80 /// acknowledgment of delivery and no retry mechanism. This is the
81 /// fastest delivery method but provides no guarantee that the message
82 /// will be received.
83 ///
84 /// This level is suitable for:
85 /// - High-frequency sensor data where missing occasional readings is acceptable
86 /// - Applications where message loss is tolerable
87 /// - Scenarios where network bandwidth and battery life are critical
88 AtMostOnce = 0,
89
90 /// QoS level 1: At least once delivery
91 ///
92 /// Messages are delivered at least once. The receiver acknowledges
93 /// delivery with a PUBACK packet. If the sender doesn't receive the
94 /// acknowledgment within a reasonable time, it retransmits the message.
95 /// Duplicate messages may occur and should be handled by the application.
96 ///
97 /// This level is suitable for:
98 /// - Applications that can handle duplicate messages
99 /// - Scenarios where message delivery is important but duplicates are acceptable
100 /// - Most general-purpose messaging use cases
101 AtLeastOnce = 1,
102
103 /// QoS level 2: Exactly once delivery
104 ///
105 /// Messages are delivered exactly once using a four-part handshake
106 /// protocol (PUBLISH -> PUBREC -> PUBREL -> PUBCOMP). This guarantees
107 /// that messages are neither lost nor duplicated, but requires the
108 /// most network traffic and processing overhead.
109 ///
110 /// This level is suitable for:
111 /// - Financial transactions or billing information
112 /// - Critical control messages
113 /// - Applications where duplicate processing would cause serious problems
114 ExactlyOnce = 2,
115}
116
117/// Implementation of `Display` for `Qos`
118///
119/// Formats the QoS level as a human-readable string representation.
120/// This allows QoS values to be used with `println!`, `format!`, and
121/// other string formatting operations.
122///
123/// # Output Format
124///
125/// * `Qos::AtMostOnce` -> "AtMostOnce"
126/// * `Qos::AtLeastOnce` -> "AtLeastOnce"
127/// * `Qos::ExactlyOnce` -> "ExactlyOnce"
128impl fmt::Display for Qos {
129 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
130 let s = match self {
131 Self::AtMostOnce => "AtMostOnce",
132 Self::AtLeastOnce => "AtLeastOnce",
133 Self::ExactlyOnce => "ExactlyOnce",
134 };
135 write!(f, "{s}")
136 }
137}