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