mqtt_topic_engine/qos.rs
1//! Quality of Service (QoS) levels for MQTT
2//!
3//! Defines the three standard MQTT QoS levels independent of any specific
4//! MQTT client implementation.
5//!
6//! This module provides conversions to/from popular MQTT client libraries:
7//! - `rumqttc` - Enable with feature `rumqttc`
8//! - `paho-mqtt` - Enable with feature `paho-mqtt`
9//! - `ntex-mqtt` - Enable with feature `ntex-mqtt`
10//!
11//! These features only add **type conversions** between [`QoS`] and the client's
12//! own QoS type — they pull in the client crate purely for its types and do not
13//! drive any connection. How that client itself is built stays under your
14//! control: this crate depends on each with `default-features = false`, so it
15//! never forces a native toolchain on you. In particular `paho-mqtt` links a
16//! C library — its default `bundled` feature builds it from source (needs CMake)
17//! while otherwise it expects a system-installed Paho C library. Since you would
18//! only enable the `paho-mqtt` feature when you already use `paho-mqtt` as your
19//! client, Cargo's (additive) feature unification applies your own build choice
20//! there, and everything links as expected.
21
22use std::fmt;
23
24/// MQTT Quality of Service levels
25///
26/// Defines delivery guarantees for MQTT messages:
27/// - `AtMostOnce` (0): Best effort delivery, no guarantees
28/// - `AtLeastOnce` (1): Message delivered at least once, duplicates possible
29/// - `ExactlyOnce` (2): Message delivered exactly once, highest guarantee
30#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
31#[repr(u8)]
32pub enum QoS {
33 /// QoS 0: At most once delivery (fire and forget)
34 AtMostOnce = 0,
35 /// QoS 1: At least once delivery (acknowledged delivery)
36 AtLeastOnce = 1,
37 /// QoS 2: Exactly once delivery (assured delivery)
38 ExactlyOnce = 2,
39}
40
41impl QoS {
42 /// Convert to rumqttc QoS type
43 ///
44 /// # Example
45 /// ```ignore
46 /// let qos = QoS::AtLeastOnce;
47 /// let rumqttc_qos = qos.to_rumqttc();
48 /// ```
49 #[cfg(feature = "rumqttc")]
50 pub fn to_rumqttc(self) -> rumqttc::QoS {
51 match self {
52 | QoS::AtMostOnce => rumqttc::QoS::AtMostOnce,
53 | QoS::AtLeastOnce => rumqttc::QoS::AtLeastOnce,
54 | QoS::ExactlyOnce => rumqttc::QoS::ExactlyOnce,
55 }
56 }
57
58 /// Convert to paho-mqtt QoS type
59 ///
60 /// # Example
61 /// ```ignore
62 /// let qos = QoS::AtLeastOnce;
63 /// let paho_qos = qos.to_paho_mqtt();
64 /// ```
65 #[cfg(feature = "paho-mqtt")]
66 pub fn to_paho_mqtt(self) -> paho_mqtt::QoS {
67 match self {
68 | QoS::AtMostOnce => paho_mqtt::QoS::AtMostOnce,
69 | QoS::AtLeastOnce => paho_mqtt::QoS::AtLeastOnce,
70 | QoS::ExactlyOnce => paho_mqtt::QoS::ExactlyOnce,
71 }
72 }
73
74 /// Convert to ntex-mqtt QoS type
75 ///
76 /// # Example
77 /// ```ignore
78 /// let qos = QoS::AtLeastOnce;
79 /// let ntex_qos = qos.to_ntex_mqtt();
80 /// ```
81 #[cfg(feature = "ntex-mqtt")]
82 pub fn to_ntex_mqtt(self) -> ntex_mqtt::QoS {
83 match self {
84 | QoS::AtMostOnce => ntex_mqtt::QoS::AtMostOnce,
85 | QoS::AtLeastOnce => ntex_mqtt::QoS::AtLeastOnce,
86 | QoS::ExactlyOnce => ntex_mqtt::QoS::ExactlyOnce,
87 }
88 }
89}
90
91#[cfg(feature = "rumqttc")]
92impl From<rumqttc::QoS> for QoS {
93 fn from(qos: rumqttc::QoS) -> Self {
94 match qos {
95 | rumqttc::QoS::AtMostOnce => QoS::AtMostOnce,
96 | rumqttc::QoS::AtLeastOnce => QoS::AtLeastOnce,
97 | rumqttc::QoS::ExactlyOnce => QoS::ExactlyOnce,
98 }
99 }
100}
101
102#[cfg(feature = "paho-mqtt")]
103impl From<paho_mqtt::QoS> for QoS {
104 fn from(qos: paho_mqtt::QoS) -> Self {
105 match qos {
106 | paho_mqtt::QoS::AtMostOnce => QoS::AtMostOnce,
107 | paho_mqtt::QoS::AtLeastOnce => QoS::AtLeastOnce,
108 | paho_mqtt::QoS::ExactlyOnce => QoS::ExactlyOnce,
109 }
110 }
111}
112
113#[cfg(feature = "ntex-mqtt")]
114impl From<ntex_mqtt::QoS> for QoS {
115 fn from(qos: ntex_mqtt::QoS) -> Self {
116 match qos {
117 | ntex_mqtt::QoS::AtMostOnce => QoS::AtMostOnce,
118 | ntex_mqtt::QoS::AtLeastOnce => QoS::AtLeastOnce,
119 | ntex_mqtt::QoS::ExactlyOnce => QoS::ExactlyOnce,
120 }
121 }
122}
123
124impl fmt::Display for QoS {
125 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
126 match self {
127 | QoS::AtMostOnce => write!(f, "QoS0"),
128 | QoS::AtLeastOnce => write!(f, "QoS1"),
129 | QoS::ExactlyOnce => write!(f, "QoS2"),
130 }
131 }
132}