mqttrs2/
packet.rs

1#[cfg(feature = "defmt")]
2use defmt::Format;
3
4use crate::*;
5
6/// Base enum for all MQTT packet types.
7///
8/// This is the main type you'll be interacting with, as an output of [`decode_slice()`] and an input of
9/// [`encode()`]. Most variants can be constructed directly without using methods.
10///
11/// ```
12/// # use mqttrs2::*;
13/// # use core::convert::TryFrom;
14/// // Simplest form
15/// let pkt = Packet::Connack(Connack { session_present: false,
16///                                     code: ConnectReturnCode::Accepted });
17/// // Using `Into` trait
18/// let publish = Publish { dup: false,
19///                         qospid: QosPid::AtMostOnce,
20///                         retain: false,
21///                         topic_name: "to/pic",
22///                         payload: b"payload" };
23/// let pkt: Packet = publish.into();
24/// // Identifyer-only packets
25/// let pkt = Packet::Puback(Pid::try_from(42).unwrap());
26/// ```
27///
28/// [`encode()`]: fn.encode.html
29/// [`decode_slice()`]: fn.decode_slice.html
30#[cfg_attr(feature = "defmt", derive(Format))]
31#[derive(Debug, Clone, PartialEq)]
32pub enum Packet<'a> {
33    /// [MQTT 3.1](http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718028)
34    Connect(Connect<'a>),
35    /// [MQTT 3.2](http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718033)
36    Connack(Connack),
37    /// [MQTT 3.3](http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718037)
38    Publish(Publish<'a>),
39    /// [MQTT 3.4](http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718043)
40    Puback(Pid),
41    /// [MQTT 3.5](http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718048)
42    Pubrec(Pid),
43    /// [MQTT 3.6](http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718053)
44    Pubrel(Pid),
45    /// [MQTT 3.7](http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718058)
46    Pubcomp(Pid),
47    /// [MQTT 3.8](http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718063)
48    Subscribe(Subscribe),
49    /// [MQTT 3.9](http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718068)
50    Suback(Suback),
51    /// [MQTT 3.10](http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718072)
52    Unsubscribe(Unsubscribe),
53    /// [MQTT 3.11](http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718077)
54    Unsuback(Pid),
55    /// [MQTT 3.12](http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718081)
56    Pingreq,
57    /// [MQTT 3.13](http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718086)
58    Pingresp,
59    /// [MQTT 3.14](http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718090)
60    Disconnect,
61}
62impl<'a> Packet<'a> {
63    /// Return the packet type variant.
64    ///
65    /// This can be used for matching, categorising, debuging, etc. Most users will match directly
66    /// on `Packet` instead.
67    pub fn get_type(&self) -> PacketType {
68        match self {
69            Packet::Connect(_) => PacketType::Connect,
70            Packet::Connack(_) => PacketType::Connack,
71            Packet::Publish(_) => PacketType::Publish,
72            Packet::Puback(_) => PacketType::Puback,
73            Packet::Pubrec(_) => PacketType::Pubrec,
74            Packet::Pubrel(_) => PacketType::Pubrel,
75            Packet::Pubcomp(_) => PacketType::Pubcomp,
76            Packet::Subscribe(_) => PacketType::Subscribe,
77            Packet::Suback(_) => PacketType::Suback,
78            Packet::Unsubscribe(_) => PacketType::Unsubscribe,
79            Packet::Unsuback(_) => PacketType::Unsuback,
80            Packet::Pingreq => PacketType::Pingreq,
81            Packet::Pingresp => PacketType::Pingresp,
82            Packet::Disconnect => PacketType::Disconnect,
83        }
84    }
85}
86
87macro_rules! packet_from_borrowed {
88    ($($t:ident),+) => {
89        $(
90            impl<'a> From<$t<'a>> for Packet<'a> {
91                fn from(p: $t<'a>) -> Self {
92                    Packet::$t(p)
93                }
94            }
95        )+
96    }
97}
98macro_rules! packet_from {
99    ($($t:ident),+) => {
100        $(
101            impl<'a> From<$t> for Packet<'a> {
102                fn from(p: $t) -> Self {
103                    Packet::$t(p)
104                }
105            }
106        )+
107    }
108}
109
110packet_from_borrowed!(Connect, Publish);
111packet_from!(Suback, Connack, Subscribe, Unsubscribe);
112
113/// Packet type variant, without the associated data.
114#[cfg_attr(feature = "defmt", derive(Format))]
115#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
116pub enum PacketType {
117    Connect,
118    Connack,
119    Publish,
120    Puback,
121    Pubrec,
122    Pubrel,
123    Pubcomp,
124    Subscribe,
125    Suback,
126    Unsubscribe,
127    Unsuback,
128    Pingreq,
129    Pingresp,
130    Disconnect,
131}