mqute_codec/protocol/v4/
pubrel.rs

1//! # PubRel Packet V4
2//!
3//! This module defines the `PubRel` packet, which is used in the MQTT protocol as part of the
4//! QoS 2 message flow. The `PubRel` packet is sent by the publisher to acknowledge the receipt
5//! of a `PubRec` packet and to indicate that the message can be released to subscribers.
6
7use super::util;
8use crate::codec::util::decode_word;
9use crate::codec::{Decode, Encode, RawPacket};
10use crate::protocol::{FixedHeader, Flags, PacketType, QoS};
11use crate::Error;
12use bytes::BufMut;
13
14// Defines the `PubRel` packet for MQTT V4
15util::id_packet!(PubRel);
16
17impl Encode for PubRel {
18    /// Encodes the `PubRel` packet into a byte buffer.
19    fn encode(&self, buf: &mut bytes::BytesMut) -> Result<(), Error> {
20        let header = FixedHeader::with_flags(
21            PacketType::PubRel,
22            Flags::new(QoS::AtLeastOnce),
23            self.payload_len(),
24        );
25        header.encode(buf)?;
26
27        buf.put_u16(self.packet_id);
28        Ok(())
29    }
30
31    /// Returns the length of the `PubRel` packet payload.
32    fn payload_len(&self) -> usize {
33        2
34    }
35}
36
37impl Decode for PubRel {
38    /// Decodes a `PubRel` packet from a raw MQTT packet.
39    fn decode(mut packet: RawPacket) -> Result<Self, Error> {
40        if packet.header.packet_type() != PacketType::PubRel
41            || packet.header.flags() != Flags::new(QoS::AtLeastOnce)
42        {
43            return Err(Error::MalformedPacket);
44        }
45        let packet_id = decode_word(&mut packet.payload)?;
46        Ok(PubRel::new(packet_id))
47    }
48}
49
50#[cfg(test)]
51mod tests {
52    use super::*;
53    use crate::codec::PacketCodec;
54    use crate::codec::{Decode, Encode};
55    use bytes::BytesMut;
56    use tokio_util::codec::Decoder;
57
58    #[test]
59    fn pubrel_decode() {
60        let mut codec = PacketCodec::new(None, None);
61
62        let data = &[
63            (PacketType::PubRel as u8) << 4 | 0b0010, // Packet type
64            0x02,                                     // Remaining len
65            0x12,                                     // Packet ID
66            0x34,
67        ];
68
69        let mut stream = BytesMut::new();
70
71        stream.extend_from_slice(&data[..]);
72
73        let raw_packet = codec.decode(&mut stream).unwrap().unwrap();
74        let packet = PubRel::decode(raw_packet).unwrap();
75
76        assert_eq!(packet, PubRel::new(0x1234));
77    }
78
79    #[test]
80    fn pubrel_encode() {
81        let packet = PubRel::new(0x1234);
82
83        let mut stream = BytesMut::new();
84        packet.encode(&mut stream).unwrap();
85        assert_eq!(
86            stream,
87            vec![(PacketType::PubRel as u8) << 4 | 0b0010, 0x02, 0x12, 0x34]
88        );
89    }
90}