#[derive(Debug, Clone)]
pub struct StreamBuffer<T> {
buffer: Vec<T>,
}
impl<T> StreamBuffer<T> {
pub fn new() -> Self {
Self { buffer: Vec::new() }
}
pub fn with_capacity(capacity: usize) -> Self {
Self {
buffer: Vec::with_capacity(capacity),
}
}
#[inline]
pub fn len(&self) -> usize {
self.buffer.len()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.buffer.is_empty()
}
pub fn capacity(&self) -> usize {
self.buffer.capacity()
}
#[inline]
pub fn push_slice(&mut self, samples: &[T])
where
T: Clone,
{
self.buffer.extend_from_slice(samples);
}
pub fn consume(&mut self, n: usize)
where
T: Clone,
{
let n = n.min(self.buffer.len());
self.buffer.drain(0..n);
}
#[inline]
pub fn clear(&mut self) {
self.buffer.clear();
}
#[inline]
pub fn as_slice(&self) -> &[T] {
&self.buffer
}
}
impl<T> Default for StreamBuffer<T> {
fn default() -> Self {
Self::new()
}
}
impl<T> std::ops::Index<usize> for StreamBuffer<T> {
type Output = T;
#[inline]
fn index(&self, idx: usize) -> &T {
&self.buffer[idx]
}
}
impl<T> std::ops::Index<std::ops::Range<usize>> for StreamBuffer<T> {
type Output = [T];
#[inline]
fn index(&self, range: std::ops::Range<usize>) -> &[T] {
&self.buffer[range]
}
}
impl<T> std::ops::Index<std::ops::RangeTo<usize>> for StreamBuffer<T> {
type Output = [T];
#[inline]
fn index(&self, range: std::ops::RangeTo<usize>) -> &[T] {
&self.buffer[range]
}
}
impl<T> std::ops::Index<std::ops::RangeFrom<usize>> for StreamBuffer<T> {
type Output = [T];
#[inline]
fn index(&self, range: std::ops::RangeFrom<usize>) -> &[T] {
&self.buffer[range]
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new() {
let buffer: StreamBuffer<i32> = StreamBuffer::new();
assert!(buffer.is_empty());
assert_eq!(buffer.len(), 0);
}
#[test]
fn test_with_capacity() {
let buffer: StreamBuffer<i32> = StreamBuffer::with_capacity(100);
assert_eq!(buffer.capacity(), 100);
assert_eq!(buffer.len(), 0);
}
#[test]
fn test_push_slice() {
let mut buffer = StreamBuffer::new();
buffer.push_slice(&[1, 2, 3]);
assert_eq!(buffer.len(), 3);
buffer.push_slice(&[4, 5]);
assert_eq!(buffer.len(), 5);
}
#[test]
fn test_consume() {
let mut buffer = StreamBuffer::new();
buffer.push_slice(&[1, 2, 3, 4, 5]);
buffer.consume(2);
assert_eq!(buffer.len(), 3);
assert_eq!(buffer.as_slice(), &[3, 4, 5]);
}
#[test]
fn test_consume_exceeds_length() {
let mut buffer = StreamBuffer::new();
buffer.push_slice(&[1, 2, 3]);
buffer.consume(10); assert!(buffer.is_empty());
}
#[test]
fn test_clear() {
let mut buffer = StreamBuffer::new();
buffer.push_slice(&[1, 2, 3]);
buffer.clear();
assert!(buffer.is_empty());
assert_eq!(buffer.len(), 0);
}
#[test]
fn test_indexing() {
let mut buffer = StreamBuffer::new();
buffer.push_slice(&[10, 20, 30, 40, 50]);
assert_eq!(buffer[0], 10);
assert_eq!(buffer[2], 30);
assert_eq!(buffer[0..3], [10, 20, 30]);
}
#[test]
fn test_as_slice() {
let mut buffer = StreamBuffer::new();
buffer.push_slice(&[1, 2, 3]);
assert_eq!(buffer.as_slice(), &[1, 2, 3]);
}
#[test]
fn test_streaming_pattern() {
let mut buffer = StreamBuffer::new();
buffer.push_slice(&vec![1; 100]);
assert_eq!(buffer.len(), 100);
let groups = buffer.len() / 32;
assert_eq!(groups, 3);
buffer.consume(96);
assert_eq!(buffer.len(), 4);
buffer.push_slice(&vec![2; 96]);
assert_eq!(buffer.len(), 100);
let groups = buffer.len() / 32;
assert_eq!(groups, 3);
buffer.consume(96);
assert_eq!(buffer.len(), 4);
}
#[test]
fn test_default() {
let buffer: StreamBuffer<i32> = StreamBuffer::default();
assert!(buffer.is_empty());
}
}