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}