limq 0.4.0

Queue with a controller for monitoring queue elements
Documentation
use std::{cmp, collections::VecDeque, marker::PhantomData};

use super::{CheckErr, Controller};

/// [`LimQ`](crate::LimQ) controller that imposes an _optional_ queue length
/// limit.
pub struct OptLenLim<T> {
  q_len: usize,
  max_len: Option<usize>,
  len_hwm: usize,
  _phantom: PhantomData<T>
}

impl<T> OptLenLim<T> {
  /// Create a new object for limiting queue to a configured length.
  ///
  /// # Panics
  /// `max_len` must not be `0`.
  #[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
    }
  }

  /// Return the current maximum length setting.
  #[must_use]
  pub const fn get_max_len(&self) -> Option<usize> {
    self.max_len
  }

  /// Update the maximum queue length.
  ///
  /// # Panics
  /// `max_len` must not be `0`.
  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;
  }

  /// Retreive the current queue length high-water mark.
  #[must_use]
  pub const fn get_len_hwm(&self) -> usize {
    self.len_hwm
  }

  /// Set the queue length high-water mark to the current queue length.
  pub const fn reset_len_hwm(&mut self) {
    self.len_hwm = self.q_len;
  }

  /// Set the queue length high-water mark to `0`.
  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;
  }
}

// vim: set ft=rust et sw=2 ts=2 sts=2 cinoptions=2 tw=79 :