mqtt_protocol_core/mqtt/packet/
enum_packet.rs

1use crate::mqtt::packet::PacketType;
2/**
3 * MIT License
4 *
5 * Copyright (c) 2025 Takatoshi Kondo
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in all
15 * copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 */
25use crate::mqtt::packet::v3_1_1;
26use crate::mqtt::packet::v5_0;
27use crate::mqtt::packet::IsPacketId;
28use crate::mqtt::version::Version;
29use enum_dispatch::enum_dispatch;
30use serde::Serialize;
31use std::io::IoSlice;
32
33#[enum_dispatch]
34pub trait GenericPacketTrait {
35    fn size(&self) -> usize;
36    fn to_buffers(&self) -> Vec<IoSlice<'_>>;
37}
38
39#[enum_dispatch]
40pub trait GenericPacketDisplay {
41    fn fmt_debug(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result;
42    fn fmt_display(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result;
43}
44
45#[enum_dispatch(GenericPacketTrait, GenericPacketDisplay)]
46#[derive(Serialize, Clone, PartialEq, Eq)]
47pub enum GenericPacket<PacketIdType>
48where
49    PacketIdType: IsPacketId + Serialize,
50{
51    V3_1_1Connect(v3_1_1::Connect),
52    V3_1_1Connack(v3_1_1::Connack),
53    V3_1_1Subscribe(v3_1_1::GenericSubscribe<PacketIdType>),
54    V3_1_1Suback(v3_1_1::GenericSuback<PacketIdType>),
55    V3_1_1Unsubscribe(v3_1_1::GenericUnsubscribe<PacketIdType>),
56    V3_1_1Unsuback(v3_1_1::GenericUnsuback<PacketIdType>),
57    V3_1_1Publish(v3_1_1::GenericPublish<PacketIdType>),
58    V3_1_1Puback(v3_1_1::GenericPuback<PacketIdType>),
59    V3_1_1Pubrec(v3_1_1::GenericPubrec<PacketIdType>),
60    V3_1_1Pubrel(v3_1_1::GenericPubrel<PacketIdType>),
61    V3_1_1Pubcomp(v3_1_1::GenericPubcomp<PacketIdType>),
62    V3_1_1Disconnect(v3_1_1::Disconnect),
63    V3_1_1Pingreq(v3_1_1::Pingreq),
64    V3_1_1Pingresp(v3_1_1::Pingresp),
65
66    V5_0Connect(v5_0::Connect),
67    V5_0Connack(v5_0::Connack),
68    V5_0Subscribe(v5_0::GenericSubscribe<PacketIdType>),
69    V5_0Suback(v5_0::GenericSuback<PacketIdType>),
70    V5_0Unsubscribe(v5_0::GenericUnsubscribe<PacketIdType>),
71    V5_0Unsuback(v5_0::GenericUnsuback<PacketIdType>),
72    V5_0Publish(v5_0::GenericPublish<PacketIdType>),
73    V5_0Puback(v5_0::GenericPuback<PacketIdType>),
74    V5_0Pubrec(v5_0::GenericPubrec<PacketIdType>),
75    V5_0Pubrel(v5_0::GenericPubrel<PacketIdType>),
76    V5_0Pubcomp(v5_0::GenericPubcomp<PacketIdType>),
77    V5_0Disconnect(v5_0::Disconnect),
78    V5_0Pingreq(v5_0::Pingreq),
79    V5_0Pingresp(v5_0::Pingresp),
80    V5_0Auth(v5_0::Auth),
81}
82
83// Type alias for commonly used u16 PacketIdType
84pub type Packet = GenericPacket<u16>;
85
86impl<PacketIdType> std::fmt::Debug for GenericPacket<PacketIdType>
87where
88    PacketIdType: IsPacketId + Serialize,
89{
90    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
91        self.fmt_debug(f)
92    }
93}
94
95impl<PacketIdType> std::fmt::Display for GenericPacket<PacketIdType>
96where
97    PacketIdType: IsPacketId + Serialize,
98{
99    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
100        self.fmt_display(f)
101    }
102}
103
104impl<PacketIdType> GenericPacket<PacketIdType>
105where
106    PacketIdType: IsPacketId + Serialize,
107{
108    /// Get the packet type
109    pub fn packet_type(&self) -> PacketType {
110        match self {
111            GenericPacket::V3_1_1Connect(_) => PacketType::Connect,
112            GenericPacket::V3_1_1Connack(_) => PacketType::Connack,
113            GenericPacket::V3_1_1Subscribe(_) => PacketType::Subscribe,
114            GenericPacket::V3_1_1Suback(_) => PacketType::Suback,
115            GenericPacket::V3_1_1Unsubscribe(_) => PacketType::Unsubscribe,
116            GenericPacket::V3_1_1Unsuback(_) => PacketType::Unsuback,
117            GenericPacket::V3_1_1Publish(_) => PacketType::Publish,
118            GenericPacket::V3_1_1Puback(_) => PacketType::Puback,
119            GenericPacket::V3_1_1Pubrec(_) => PacketType::Pubrec,
120            GenericPacket::V3_1_1Pubrel(_) => PacketType::Pubrel,
121            GenericPacket::V3_1_1Pubcomp(_) => PacketType::Pubcomp,
122            GenericPacket::V3_1_1Disconnect(_) => PacketType::Disconnect,
123            GenericPacket::V3_1_1Pingreq(_) => PacketType::Pingreq,
124            GenericPacket::V3_1_1Pingresp(_) => PacketType::Pingresp,
125
126            GenericPacket::V5_0Connect(_) => PacketType::Connect,
127            GenericPacket::V5_0Connack(_) => PacketType::Connack,
128            GenericPacket::V5_0Subscribe(_) => PacketType::Subscribe,
129            GenericPacket::V5_0Suback(_) => PacketType::Suback,
130            GenericPacket::V5_0Unsubscribe(_) => PacketType::Unsubscribe,
131            GenericPacket::V5_0Unsuback(_) => PacketType::Unsuback,
132            GenericPacket::V5_0Publish(_) => PacketType::Publish,
133            GenericPacket::V5_0Puback(_) => PacketType::Puback,
134            GenericPacket::V5_0Pubrec(_) => PacketType::Pubrec,
135            GenericPacket::V5_0Pubrel(_) => PacketType::Pubrel,
136            GenericPacket::V5_0Pubcomp(_) => PacketType::Pubcomp,
137            GenericPacket::V5_0Disconnect(_) => PacketType::Disconnect,
138            GenericPacket::V5_0Pingreq(_) => PacketType::Pingreq,
139            GenericPacket::V5_0Pingresp(_) => PacketType::Pingresp,
140            GenericPacket::V5_0Auth(_) => PacketType::Auth,
141        }
142    }
143
144    /// Get the MQTT protocol version of this packet
145    pub fn protocol_version(&self) -> Version {
146        match self {
147            GenericPacket::V3_1_1Connect(_) => Version::V3_1_1,
148            GenericPacket::V3_1_1Connack(_) => Version::V3_1_1,
149            GenericPacket::V3_1_1Subscribe(_) => Version::V3_1_1,
150            GenericPacket::V3_1_1Suback(_) => Version::V3_1_1,
151            GenericPacket::V3_1_1Unsubscribe(_) => Version::V3_1_1,
152            GenericPacket::V3_1_1Unsuback(_) => Version::V3_1_1,
153            GenericPacket::V3_1_1Publish(_) => Version::V3_1_1,
154            GenericPacket::V3_1_1Puback(_) => Version::V3_1_1,
155            GenericPacket::V3_1_1Pubrec(_) => Version::V3_1_1,
156            GenericPacket::V3_1_1Pubrel(_) => Version::V3_1_1,
157            GenericPacket::V3_1_1Pubcomp(_) => Version::V3_1_1,
158            GenericPacket::V3_1_1Disconnect(_) => Version::V3_1_1,
159            GenericPacket::V3_1_1Pingreq(_) => Version::V3_1_1,
160            GenericPacket::V3_1_1Pingresp(_) => Version::V3_1_1,
161
162            GenericPacket::V5_0Connect(_) => Version::V5_0,
163            GenericPacket::V5_0Connack(_) => Version::V5_0,
164            GenericPacket::V5_0Subscribe(_) => Version::V5_0,
165            GenericPacket::V5_0Suback(_) => Version::V5_0,
166            GenericPacket::V5_0Unsubscribe(_) => Version::V5_0,
167            GenericPacket::V5_0Unsuback(_) => Version::V5_0,
168            GenericPacket::V5_0Publish(_) => Version::V5_0,
169            GenericPacket::V5_0Puback(_) => Version::V5_0,
170            GenericPacket::V5_0Pubrec(_) => Version::V5_0,
171            GenericPacket::V5_0Pubrel(_) => Version::V5_0,
172            GenericPacket::V5_0Pubcomp(_) => Version::V5_0,
173            GenericPacket::V5_0Disconnect(_) => Version::V5_0,
174            GenericPacket::V5_0Pingreq(_) => Version::V5_0,
175            GenericPacket::V5_0Pingresp(_) => Version::V5_0,
176            GenericPacket::V5_0Auth(_) => Version::V5_0,
177        }
178    }
179}