use crate::coding::encoder::{PacketLenIter, U8Iter, Unit};
use crate::coding::{Decoder, Encoder};
use crate::err;
use crate::error::{Data, DecoderError};
use crate::packets::TryFromIterator;
use core::iter::Chain;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Connack {
session_present: bool,
return_code: u8,
}
impl Connack {
pub const TYPE: u8 = 2;
const BODY_LEN: usize = 2;
pub const fn new(session_present: bool, return_code: u8) -> Self {
Self { session_present, return_code }
}
pub const fn session_present(&self) -> bool {
self.session_present
}
pub const fn return_code(&self) -> u8 {
self.return_code
}
}
impl TryFromIterator for Connack {
fn try_from_iter<T>(iter: T) -> Result<Self, DecoderError>
where
T: IntoIterator<Item = u8>,
{
let mut decoder = Decoder::new(iter);
let (Self::TYPE, _flags) = decoder.header()? else {
return Err(err!(Data::SpecViolation, "invalid packet type"))?;
};
let Self::BODY_LEN = decoder.packetlen()? else {
return Err(err!(Data::SpecViolation, "invalid packet length"))?;
};
let [_, _, _, _, _, _, _, session_present] = decoder.bitmap()?;
let return_code = decoder.u8()?;
Ok(Self { session_present, return_code })
}
}
impl IntoIterator for Connack {
type Item = u8;
#[rustfmt::skip]
type IntoIter =
Chain<Chain<Chain<Chain<
Unit, U8Iter>,
PacketLenIter>,
U8Iter>,
U8Iter>;
fn into_iter(self) -> Self::IntoIter {
Encoder::default()
.header(Self::TYPE, [false, false, false, false])
.packetlen(Self::BODY_LEN)
.bitmap([false, false, false, false, false, false, false, self.session_present])
.u8(self.return_code)
.into_iter()
}
}