rsvim_core 0.1.3-alpha.2

The core library for RSVIM text editor.
Documentation
//! VecDeque based fixed-size ringbuf.

use std::collections::VecDeque;
use std::ops::Index;
use std::ops::IndexMut;

#[derive(Debug, Clone)]
/// Single-ended Ring buffer.
pub struct RingBuffer<T> {
  data: VecDeque<T>,
  max_size: usize,
}

impl<T> RingBuffer<T> {
  pub fn new(max_size: usize) -> Self {
    Self {
      data: VecDeque::with_capacity(max_size),
      max_size,
    }
  }

  pub fn is_empty(&self) -> bool {
    self.data.is_empty()
  }

  pub fn len(&self) -> usize {
    self.data.len()
  }

  pub fn max_size(&self) -> usize {
    self.max_size
  }

  /// Force push, remove eldest items if full.
  pub fn push_overwrite(&mut self, value: T) {
    while self.data.len() >= self.max_size && !self.data.is_empty() {
      self.data.pop_front();
    }
    self.data.push_back(value)
  }

  /// Try push, don't remove eldest items if full and fail.
  pub fn try_push(&mut self, value: T) -> Result<(), T> {
    if self.data.len() < self.max_size {
      self.data.push_back(value);
      Ok(())
    } else {
      Err(value)
    }
  }

  /// Pop eldest item and remove it.
  pub fn pop(&mut self) -> Option<T> {
    self.data.pop_front()
  }

  /// Peek, get eldest item without removing it.
  ///
  /// Equivalent to [`Self::first`].
  pub fn peek(&self) -> Option<&T> {
    self.data.front()
  }

  /// Get eldest item.
  pub fn first(&self) -> Option<&T> {
    self.data.front()
  }

  pub fn first_mut(&mut self) -> Option<&mut T> {
    self.data.front_mut()
  }

  /// Get latest item.
  pub fn last(&self) -> Option<&T> {
    self.data.back()
  }

  pub fn last_mut(&mut self) -> Option<&mut T> {
    self.data.back_mut()
  }

  pub fn iter(&'_ self) -> std::collections::vec_deque::Iter<'_, T> {
    self.data.iter()
  }

  pub fn drain<R>(
    &mut self,
    range: R,
  ) -> std::collections::vec_deque::Drain<'_, T>
  where
    R: std::ops::RangeBounds<usize>,
  {
    self.data.drain(range)
  }
}

impl<T> Index<usize> for RingBuffer<T> {
  type Output = T;

  fn index(&self, index: usize) -> &Self::Output {
    self.data.index(index)
  }
}

impl<T> IndexMut<usize> for RingBuffer<T> {
  fn index_mut(&mut self, index: usize) -> &mut Self::Output {
    self.data.index_mut(index)
  }
}

#[derive(Debug, Clone)]
/// Double-ended ring buffer.
pub struct DeRingBuffer<T> {
  data: VecDeque<T>,
  max_size: usize,
}

impl<T> DeRingBuffer<T> {
  pub fn new(max_size: usize) -> Self {
    Self {
      data: VecDeque::with_capacity(max_size),
      max_size,
    }
  }

  pub fn is_empty(&self) -> bool {
    self.data.is_empty()
  }

  pub fn len(&self) -> usize {
    self.data.len()
  }

  pub fn max_size(&self) -> usize {
    self.max_size
  }

  /// Force push back, remove eldest items if full.
  pub fn push_back_overwrite(&mut self, value: T) {
    while self.data.len() >= self.max_size && !self.data.is_empty() {
      self.data.pop_front();
    }
    self.data.push_back(value)
  }

  /// Try push back, don't remove eldest items if full and fail.
  pub fn try_push_back(&mut self, value: T) -> Result<(), T> {
    if self.data.len() < self.max_size {
      self.data.push_back(value);
      Ok(())
    } else {
      Err(value)
    }
  }

  pub fn pop_front(&mut self) -> Option<T> {
    self.data.pop_front()
  }

  pub fn pop_back(&mut self) -> Option<T> {
    self.data.pop_back()
  }

  pub fn front(&self) -> Option<&T> {
    self.data.front()
  }

  pub fn front_mut(&mut self) -> Option<&mut T> {
    self.data.front_mut()
  }

  pub fn back(&self) -> Option<&T> {
    self.data.back()
  }

  pub fn back_mut(&mut self) -> Option<&mut T> {
    self.data.back_mut()
  }

  pub fn iter(&'_ self) -> std::collections::vec_deque::Iter<'_, T> {
    self.data.iter()
  }

  pub fn drain<R>(
    &mut self,
    range: R,
  ) -> std::collections::vec_deque::Drain<'_, T>
  where
    R: std::ops::RangeBounds<usize>,
  {
    self.data.drain(range)
  }
}

impl<T> Index<usize> for DeRingBuffer<T> {
  type Output = T;

  fn index(&self, index: usize) -> &Self::Output {
    self.data.index(index)
  }
}

impl<T> IndexMut<usize> for DeRingBuffer<T> {
  fn index_mut(&mut self, index: usize) -> &mut Self::Output {
    self.data.index_mut(index)
  }
}