use std::{cmp, collections::VecDeque, marker::PhantomData};
use super::{CheckErr, Controller};
pub struct OptLenLim<T> {
q_len: usize,
max_len: Option<usize>,
len_hwm: usize,
_phantom: PhantomData<T>
}
impl<T> OptLenLim<T> {
#[must_use]
pub fn new(max_len: Option<usize>) -> Self {
assert!(!matches!(max_len, Some(0)), "zero-length limit");
Self {
q_len: 0,
max_len,
len_hwm: 0,
_phantom: PhantomData
}
}
#[must_use]
pub const fn get_max_len(&self) -> Option<usize> {
self.max_len
}
pub fn set_max_len(&mut self, max_len: Option<usize>) {
assert!(!matches!(max_len, Some(0)), "zero-length limit");
self.max_len = max_len;
}
#[must_use]
pub const fn get_len_hwm(&self) -> usize {
self.len_hwm
}
pub const fn reset_len_hwm(&mut self) {
self.len_hwm = self.q_len;
}
pub const fn clear_len_hwm(&mut self) {
self.len_hwm = 0;
}
}
impl<T> Controller for OptLenLim<T> {
type Item = T;
fn size_hint(&self) -> Option<usize> {
self.max_len
}
fn is_full(&self, q: &VecDeque<T>) -> bool {
self.max_len.is_some_and(|max_len| q.len() >= max_len)
}
fn is_overflow(&self, q: &VecDeque<T>) -> bool {
self.max_len.is_some_and(|max_len| q.len() > max_len)
}
fn check(
&self,
q: &VecDeque<Self::Item>,
_n: &Self::Item
) -> Result<(), CheckErr> {
self
.max_len
.is_some_and(|max_len| q.len() < max_len)
.then_some(())
.ok_or(CheckErr::WontFit)
}
fn reg(&mut self, _q: &VecDeque<Self::Item>, _n: &Self::Item) {
self.q_len += 1;
self.len_hwm = cmp::max(self.len_hwm, self.q_len);
}
fn dereg(&mut self, _n: &Self::Item) {
self.q_len -= 1;
}
}