Skip to main content

mqtt_proto/
lib.rs

1//! MQTT wire protocol: packet encoding/decoding for both MQTT 3.1.1 and
2//! MQTT 5.0.
3//!
4//! This crate has no networking, async or TLS dependencies: it is a pure,
5//! synchronous codec so it can be unit-tested byte-for-byte and reused by the
6//! `stem-mqtt-client` connection loop, the `stem-mqtt-broker`, and firmware on
7//! embedded targets that bring their own transport.
8
9#[cfg(doctest)]
10#[doc = include_str!("../README.md")]
11struct ReadmeDoctests;
12
13pub mod ack;
14pub mod connect;
15pub mod error;
16mod macros;
17pub mod packet;
18pub mod properties;
19pub mod publish;
20pub mod subscribe;
21pub mod support;
22pub mod topic;
23pub mod varint;
24
25pub use ack::*;
26pub use connect::*;
27pub use error::{MqttError, MqttResult};
28pub use packet::*;
29pub use properties::*;
30pub use publish::*;
31pub use subscribe::*;
32
33/// The MQTT protocol version negotiated for a connection.
34#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
35pub enum MqttVersion {
36    /// MQTT 3.1.1 (protocol level 4).
37    V311,
38    /// MQTT 5.0 (protocol level 5).
39    V5,
40}
41
42impl MqttVersion {
43    pub fn protocol_level(self) -> u8 {
44        match self {
45            MqttVersion::V311 => 4,
46            MqttVersion::V5 => 5,
47        }
48    }
49
50    pub fn from_protocol_level(level: u8) -> Option<Self> {
51        match level {
52            4 => Some(MqttVersion::V311),
53            5 => Some(MqttVersion::V5),
54            _ => None,
55        }
56    }
57
58    pub fn is_v5(self) -> bool {
59        matches!(self, MqttVersion::V5)
60    }
61}
62
63/// MQTT Quality of Service level.
64#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
65pub enum QoS {
66    /// QoS 0 — fire and forget, no acknowledgement.
67    AtMostOnce,
68    /// QoS 1 — acknowledged delivery, may be duplicated.
69    AtLeastOnce,
70    /// QoS 2 — exactly-once delivery via a four-part handshake.
71    ExactlyOnce,
72}
73
74impl QoS {
75    pub fn as_u8(self) -> u8 {
76        match self {
77            QoS::AtMostOnce => 0,
78            QoS::AtLeastOnce => 1,
79            QoS::ExactlyOnce => 2,
80        }
81    }
82
83    pub fn from_u8(v: u8) -> Option<Self> {
84        match v {
85            0 => Some(QoS::AtMostOnce),
86            1 => Some(QoS::AtLeastOnce),
87            2 => Some(QoS::ExactlyOnce),
88            _ => None,
89        }
90    }
91}