mqtt_codec_kit/common/variable_header/
connect_flags.rs1use std::io::{self, Read, Write};
2
3use byteorder::{ReadBytesExt, WriteBytesExt};
4
5use crate::common::{Decodable, Encodable};
6
7#[derive(Debug, Eq, PartialEq, Copy, Clone)]
9pub struct ConnectFlags {
10 pub username: bool,
11 pub password: bool,
12 pub will_retain: bool,
13 pub will_qos: u8,
14 pub will_flag: bool,
15 pub clean_session: bool,
16 pub reserved: bool,
18}
19
20impl ConnectFlags {
21 pub fn empty() -> ConnectFlags {
22 ConnectFlags {
23 username: false,
24 password: false,
25 will_retain: false,
26 will_qos: 0,
27 will_flag: false,
28 clean_session: false,
29 reserved: false,
30 }
31 }
32}
33
34impl Encodable for ConnectFlags {
35 fn encode<W: Write>(&self, writer: &mut W) -> Result<(), io::Error> {
36 let code = ((self.username as u8) << 7)
37 | ((self.password as u8) << 6)
38 | ((self.will_retain as u8) << 5)
39 | ((self.will_qos) << 3)
40 | ((self.will_flag as u8) << 2)
41 | ((self.clean_session as u8) << 1);
42
43 writer.write_u8(code)
44 }
45
46 fn encoded_length(&self) -> u32 {
47 1
48 }
49}
50
51impl Decodable for ConnectFlags {
52 type Error = ConnectFlagsError;
53 type Cond = ();
54
55 fn decode_with<R: Read>(reader: &mut R, _rest: ()) -> Result<ConnectFlags, ConnectFlagsError> {
56 let code = reader.read_u8()?;
57 if code & 1 != 0 {
58 return Err(ConnectFlagsError::InvalidReservedFlag);
59 }
60
61 Ok(ConnectFlags {
62 username: (code & 0b1000_0000) != 0,
63 password: (code & 0b0100_0000) != 0,
64 will_retain: (code & 0b0010_0000) != 0,
65 will_qos: (code & 0b0001_1000) >> 3,
66 will_flag: (code & 0b0000_0100) != 0,
67 clean_session: (code & 0b0000_0010) != 0,
68 reserved: (code & 0b0000_0001) != 0,
69 })
70 }
71}
72
73#[derive(Debug, thiserror::Error)]
74#[error(transparent)]
75pub enum ConnectFlagsError {
76 IoError(#[from] io::Error),
77 #[error("invalid reserved flag")]
78 InvalidReservedFlag,
79}