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 a queue length limit.
pub struct LengthLimit<T> {
  /// Keep track of queue length.
  ///
  /// Normally one would simple call `len()` on the queue, but the queue is
  /// not available in [`LengthLimit::reset_len_hwm()`].
  q_len: usize,

  /// Maximum queue length.
  max_len: usize,

  /// Queue length high-water mark.
  len_hwm: usize,

  _phantom: PhantomData<T>
}

impl<T> LengthLimit<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: usize) -> Self {
    assert_ne!(max_len, 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) -> 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: usize) {
    assert_ne!(max_len, 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 LengthLimit<T> {
  type Item = T;

  fn size_hint(&self) -> Option<usize> {
    Some(self.max_len)
  }

  fn is_full(&self, q: &VecDeque<T>) -> bool {
    q.len() >= self.max_len
  }

  fn is_overflow(&self, q: &VecDeque<T>) -> bool {
    q.len() > self.max_len
  }

  fn check(
    &self,
    q: &VecDeque<Self::Item>,
    _n: &Self::Item
  ) -> Result<(), CheckErr> {
    (q.len() < self.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 :