1use std::io::Read;
4
5use crate::control::variable_header::{ConnackFlags, ConnectReturnCode};
6use crate::control::{ControlType, FixedHeader, PacketType};
7use crate::packet::{DecodablePacket, PacketError};
8use crate::Decodable;
9
10#[derive(Debug, Eq, PartialEq, Clone)]
12pub struct ConnackPacket {
13 fixed_header: FixedHeader,
14 flags: ConnackFlags,
15 ret_code: ConnectReturnCode,
16}
17
18encodable_packet!(ConnackPacket(flags, ret_code));
19
20impl ConnackPacket {
21 pub fn new(session_present: bool, ret_code: ConnectReturnCode) -> ConnackPacket {
22 ConnackPacket {
23 fixed_header: FixedHeader::new(PacketType::with_default(ControlType::ConnectAcknowledgement), 2),
24 flags: ConnackFlags { session_present },
25 ret_code,
26 }
27 }
28
29 pub fn connack_flags(&self) -> ConnackFlags {
30 self.flags
31 }
32
33 pub fn connect_return_code(&self) -> ConnectReturnCode {
34 self.ret_code
35 }
36}
37
38impl DecodablePacket for ConnackPacket {
39 type DecodePacketError = std::convert::Infallible;
40
41 fn decode_packet<R: Read>(reader: &mut R, fixed_header: FixedHeader) -> Result<Self, PacketError<Self>> {
42 let flags: ConnackFlags = Decodable::decode(reader)?;
43 let code: ConnectReturnCode = Decodable::decode(reader)?;
44
45 Ok(ConnackPacket {
46 fixed_header,
47 flags,
48 ret_code: code,
49 })
50 }
51}
52
53#[cfg(test)]
54mod test {
55 use super::*;
56
57 use std::io::Cursor;
58
59 use crate::control::variable_header::ConnectReturnCode;
60 use crate::{Decodable, Encodable};
61
62 #[test]
63 pub fn test_connack_packet_basic() {
64 let packet = ConnackPacket::new(false, ConnectReturnCode::IdentifierRejected);
65
66 let mut buf = Vec::new();
67 packet.encode(&mut buf).unwrap();
68
69 let mut decode_buf = Cursor::new(buf);
70 let decoded = ConnackPacket::decode(&mut decode_buf).unwrap();
71
72 assert_eq!(packet, decoded);
73 }
74}