use crate::core::PacketNumber;
use crate::core::packet::header::PACKET_NUMBER_LEN;
pub const MAX_ACK_RANGES: usize = 4;
pub(crate) const ACK_RANGE_COUNT_LEN: usize = core::mem::size_of::<u8>();
pub(crate) const ACK_LEN: usize =
PACKET_NUMBER_LEN + ACK_RANGE_COUNT_LEN + MAX_ACK_RANGES * 2 * PACKET_NUMBER_LEN;
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct AckRange {
pub start: PacketNumber,
pub end: PacketNumber,
}
impl AckRange {
#[must_use]
pub const fn new(start: PacketNumber, end: PacketNumber) -> Self {
Self { start, end }
}
#[must_use]
pub const fn contains(self, packet_number: PacketNumber) -> bool {
self.start.get() <= packet_number.get() && packet_number.get() <= self.end.get()
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct Ack {
pub largest_acknowledged: PacketNumber,
pub range_count: u8,
pub ranges: [AckRange; MAX_ACK_RANGES],
}
impl Ack {
#[must_use]
pub const fn new(largest_acknowledged: PacketNumber) -> Self {
let range = AckRange::new(largest_acknowledged, largest_acknowledged);
Self {
largest_acknowledged,
range_count: 1,
ranges: [range; MAX_ACK_RANGES],
}
}
#[must_use]
pub const fn from_ranges(ranges: [AckRange; MAX_ACK_RANGES], range_count: u8) -> Self {
let mut largest = PacketNumber::ZERO;
let mut index = 0;
while index < MAX_ACK_RANGES {
if index < range_count as usize && ranges[index].end.get() > largest.get() {
largest = ranges[index].end;
}
index += 1;
}
Self {
largest_acknowledged: largest,
range_count,
ranges,
}
}
#[must_use]
pub const fn ranges(self) -> [AckRange; MAX_ACK_RANGES] {
self.ranges
}
#[must_use]
pub const fn acknowledges(self, packet_number: PacketNumber) -> bool {
let mut index = 0;
while index < MAX_ACK_RANGES {
if index < self.range_count as usize && self.ranges[index].contains(packet_number) {
return true;
}
index += 1;
}
false
}
}