mqute_codec/protocol/v5/pubrec.rs
1//! # Publish Received (PubRec) Packet - MQTT v5
2//!
3//! This module implements the MQTT v5 `PubRec` packet, which is the second packet in the
4//! Quality of Service 2 (QoS 2) message delivery flow. The `PubRec` packet is sent by the
5//! receiver to acknowledge receipt of a QoS 2 PUBLISH packet.
6
7use crate::protocol::v5::reason::ReasonCode;
8use crate::protocol::v5::util::{
9 ack, ack_decode_impl, ack_encode_impl, ack_properties, ack_properties_frame_impl,
10};
11use crate::protocol::{Flags, PacketType};
12
13/// Validates reason codes for `PubRec` packets
14///
15/// MQTT v5 specifies the following valid reason codes for `PubRec`:
16/// - 0x00 (Success) - Packet accepted and stored
17/// - 0x10 (No matching subscribers) - No subscribers for the topic
18/// - 0x80 (Unspecified error) - Unspecified error condition
19/// - 0x83 (Implementation specific error) - Implementation-specific error
20/// - 0x87 (Not authorized) - Client not authorized
21/// - 0x90 (Topic Name invalid) - Malformed topic name
22/// - 0x91 (Packet Identifier in use) - Duplicate packet ID
23/// - 0x97 (Quota exceeded) - Message quota exceeded
24/// - 0x99 (Payload format invalid) - Invalid payload format
25fn validate_pubrec_reason_code(code: ReasonCode) -> bool {
26 matches!(
27 code.into(),
28 0 | 16 | 128 | 131 | 135 | 144 | 145 | 151 | 153
29 )
30}
31
32// Defines properties specific to `PubRec` packets
33ack_properties!(PubRecProperties);
34
35// Implements the PropertyFrame trait for PubRecProperties
36ack_properties_frame_impl!(PubRecProperties);
37
38// Represents an MQTT v5 `PubRec` packet
39ack!(PubRec, PubRecProperties, validate_pubrec_reason_code);
40
41// Implements packet decoding for `PubRec`
42ack_decode_impl!(
43 PubRec,
44 PacketType::PubRec,
45 Flags::default(),
46 validate_pubrec_reason_code
47);
48
49// Implements packet encoding for `PubRec`
50ack_encode_impl!(PubRec, PacketType::PubRec, Flags::default());
51
52#[cfg(test)]
53mod tests {
54 use super::*;
55 use crate::codec::PacketCodec;
56 use crate::codec::{Decode, Encode};
57 use bytes::BytesMut;
58 use tokio_util::codec::Decoder;
59
60 #[test]
61 fn pubrec_decode() {
62 let mut codec = PacketCodec::new(None, None);
63
64 let data = &[
65 (PacketType::PubRec as u8) << 4, // Packet type
66 0x04, // Remaining len
67 0x12, // Packet ID
68 0x34, //
69 0x00, // Reason code
70 0x00, // Property len
71 ];
72
73 let mut stream = BytesMut::new();
74
75 stream.extend_from_slice(&data[..]);
76
77 let raw_packet = codec.decode(&mut stream).unwrap().unwrap();
78 let packet = PubRec::decode(raw_packet).unwrap();
79
80 assert_eq!(packet, PubRec::new(0x1234, ReasonCode::Success, None));
81 }
82
83 #[test]
84 fn pubrec_encode() {
85 let packet = PubRec::new(0x1234, ReasonCode::Success, None);
86
87 let mut stream = BytesMut::new();
88 packet.encode(&mut stream).unwrap();
89 assert_eq!(
90 stream,
91 vec![
92 (PacketType::PubRec as u8) << 4, // Packet type
93 0x02, // Remaining len
94 0x12, // Packet ID
95 0x34, //
96 ]
97 );
98 }
99}