use bitflags::bitflags;
use crate::seq::Seq;
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct Header(u8);
bitflags! {
impl Header: u8 {
const FRAME_NUM = 0b0111_0000;
const RETRANSMIT = 0b0000_1000;
const ACK_NUM = 0b0000_0111;
}
}
impl Header {
#[must_use]
pub const fn new(frame_num: Seq, retransmit: bool, ack_num: Seq) -> Self {
let mut raw = Self::FRAME_NUM.bits()
& (frame_num.as_u8() << Self::FRAME_NUM.bits().trailing_zeros())
| Self::ACK_NUM.bits() & ack_num.as_u8();
if retransmit {
raw |= Self::RETRANSMIT.bits();
}
Self(raw)
}
#[must_use]
pub fn frame_num(self) -> Seq {
Seq::try_from(
(self.bits() & Self::FRAME_NUM.bits()) >> Self::FRAME_NUM.bits().trailing_zeros(),
)
.expect("Seq always fits.")
}
#[must_use]
pub fn ack_num(self) -> Seq {
Seq::try_from(self.bits() & Self::ACK_NUM.bits()).expect("Seq always fits.")
}
}
#[cfg(test)]
mod tests {
use super::Header;
#[test]
fn test_offset() {
assert_eq!(Header::FRAME_NUM.bits().trailing_zeros(), 4);
}
}