1use std::fmt;
2use std::num::NonZeroU16;
3
4use bytes::Bytes;
5use bytestring::ByteString;
6use serde::{Deserialize, Serialize};
7
8use crate::v5::PublishProperties;
9
10pub(crate) const MQTT: &[u8] = b"MQTT";
12pub(crate) const MQISDP: &[u8] = b"MQIsdp";
14pub const MQTT_LEVEL_31: u8 = 3;
16pub const MQTT_LEVEL_311: u8 = 4;
18pub const MQTT_LEVEL_5: u8 = 5;
20pub(crate) const WILL_QOS_SHIFT: u8 = 3;
22
23pub(crate) const MAX_PACKET_SIZE: u32 = 0xF_FF_FF_FF;
25
26#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
28pub struct Protocol(pub u8);
29
30impl Protocol {
31 #[inline]
33 pub fn name(self) -> &'static str {
34 match self {
35 Protocol(MQTT_LEVEL_311) => "MQTT",
36 Protocol(MQTT_LEVEL_31) => "MQIsdp",
37 Protocol(MQTT_LEVEL_5) => "MQTT",
38 Protocol(_) => "MQTT",
39 }
40 }
41
42 #[inline]
44 pub fn level(self) -> u8 {
45 self.0
46 }
47}
48
49impl Default for Protocol {
50 fn default() -> Self {
52 Protocol(MQTT_LEVEL_311)
53 }
54}
55
56prim_enum! {
57 #[derive(serde::Serialize, serde::Deserialize, PartialOrd, Ord, Hash)]
61 pub enum QoS {
62 AtMostOnce = 0,
67
68 AtLeastOnce = 1,
73
74 ExactlyOnce = 2
79 }
80}
81
82impl QoS {
83 #[inline]
85 pub fn value(&self) -> u8 {
86 match self {
87 QoS::AtMostOnce => 0,
88 QoS::AtLeastOnce => 1,
89 QoS::ExactlyOnce => 2,
90 }
91 }
92
93 #[inline]
103 pub fn less_value(&self, qos: QoS) -> QoS {
104 if self.value() < qos.value() {
105 *self
106 } else {
107 qos
108 }
109 }
110}
111
112impl From<QoS> for u8 {
113 fn from(v: QoS) -> Self {
114 v.value()
115 }
116}
117
118bitflags::bitflags! {
119 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
121 pub struct ConnectFlags: u8 {
122 const USERNAME = 0b1000_0000;
124 const PASSWORD = 0b0100_0000;
126 const WILL_RETAIN = 0b0010_0000;
128 const WILL_QOS = 0b0001_1000;
130 const WILL = 0b0000_0100;
132 const CLEAN_START = 0b0000_0010;
134 }
135}
136
137bitflags::bitflags! {
138 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
140 pub struct ConnectAckFlags: u8 {
141 const SESSION_PRESENT = 0b0000_0001;
143 }
144}
145
146pub(super) mod packet_type {
148 pub(crate) const CONNECT: u8 = 0b0001_0000;
150 pub(crate) const CONNACK: u8 = 0b0010_0000;
152 pub(crate) const PUBLISH_START: u8 = 0b0011_0000;
154 pub(crate) const PUBLISH_END: u8 = 0b0011_1111;
156 pub(crate) const PUBACK: u8 = 0b0100_0000;
158 pub(crate) const PUBREC: u8 = 0b0101_0000;
160 pub(crate) const PUBREL: u8 = 0b0110_0010;
162 pub(crate) const PUBCOMP: u8 = 0b0111_0000;
164 pub(crate) const SUBSCRIBE: u8 = 0b1000_0010;
166 pub(crate) const SUBACK: u8 = 0b1001_0000;
168 pub(crate) const UNSUBSCRIBE: u8 = 0b1010_0010;
170 pub(crate) const UNSUBACK: u8 = 0b1011_0000;
172 pub(crate) const PINGREQ: u8 = 0b1100_0000;
174 pub(crate) const PINGRESP: u8 = 0b1101_0000;
176 pub(crate) const DISCONNECT: u8 = 0b1110_0000;
178 pub(crate) const AUTH: u8 = 0b1111_0000;
180}
181
182#[derive(Debug, PartialEq, Eq, Clone, Copy)]
184pub(crate) struct FixedHeader {
185 pub(crate) first_byte: u8,
187 pub(crate) remaining_length: u32,
189}
190
191#[derive(Serialize, Deserialize, PartialEq, Eq, Clone)]
193pub struct Publish {
194 pub dup: bool,
196 pub retain: bool,
198 pub qos: QoS,
200 pub topic: ByteString,
202 pub packet_id: Option<NonZeroU16>,
204 pub payload: Bytes,
206
207 pub properties: Option<PublishProperties>,
209 pub delay_interval: Option<u32>,
211 pub create_time: Option<i64>,
213}
214
215impl fmt::Debug for Publish {
216 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
218 f.debug_struct("Publish")
219 .field("packet_id", &self.packet_id)
220 .field("topic", &self.topic)
221 .field("dup", &self.dup)
222 .field("retain", &self.retain)
223 .field("qos", &self.qos)
224 .field("payload", &"<REDACTED>")
225 .field("properties", &self.properties)
226 .field("delay_interval", &self.delay_interval)
227 .field("create_time", &self.create_time)
228 .finish()
229 }
230}