rumqttc/mqttbytes/v4/
puback.rs

1use super::*;
2use bytes::{Buf, BufMut, Bytes, BytesMut};
3
4/// Acknowledgement to QoS1 publish
5#[derive(Debug, Clone, PartialEq, Eq)]
6pub struct PubAck {
7    pub pkid: u16,
8}
9
10impl PubAck {
11    pub fn new(pkid: u16) -> PubAck {
12        PubAck { pkid }
13    }
14
15    fn len(&self) -> usize {
16        // pkid
17        2
18    }
19
20    pub fn size(&self) -> usize {
21        let len = self.len();
22        let remaining_len_size = len_len(len);
23
24        1 + remaining_len_size + len
25    }
26
27    pub fn read(fixed_header: FixedHeader, mut bytes: Bytes) -> Result<Self, Error> {
28        let variable_header_index = fixed_header.fixed_header_len;
29        bytes.advance(variable_header_index);
30        let pkid = read_u16(&mut bytes)?;
31
32        // No reason code or properties if remaining length == 2
33        if fixed_header.remaining_len == 2 {
34            return Ok(PubAck { pkid });
35        }
36
37        // No properties len or properties if remaining len > 2 but < 4
38        if fixed_header.remaining_len < 4 {
39            return Ok(PubAck { pkid });
40        }
41
42        let puback = PubAck { pkid };
43
44        Ok(puback)
45    }
46
47    pub fn write(&self, buffer: &mut BytesMut) -> Result<usize, Error> {
48        let len = self.len();
49        buffer.put_u8(0x40);
50        let count = write_remaining_length(buffer, len)?;
51        buffer.put_u16(self.pkid);
52        Ok(1 + count + len)
53    }
54}
55
56#[cfg(test)]
57mod test {
58    use super::*;
59    use bytes::BytesMut;
60    use pretty_assertions::assert_eq;
61
62    #[test]
63    fn puback_encoding_works() {
64        let stream = &[
65            0b0100_0000,
66            0x02, // packet type, flags and remaining len
67            0x00,
68            0x0A, // fixed header. packet identifier = 10
69            0xDE,
70            0xAD,
71            0xBE,
72            0xEF, // extra packets in the stream
73        ];
74        let mut stream = BytesMut::from(&stream[..]);
75        let fixed_header = parse_fixed_header(stream.iter()).unwrap();
76        let ack_bytes = stream.split_to(fixed_header.frame_length()).freeze();
77        let packet = PubAck::read(fixed_header, ack_bytes).unwrap();
78
79        assert_eq!(packet, PubAck { pkid: 10 });
80    }
81}