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