#[cfg(test)] mod test; pub struct RingBuf { data: Vec, read_index: usize, write_index: usize, available: usize, } impl RingBuf { pub fn new(size: usize, value: T) -> Self where T: Clone, { Self { data: vec![value; size], read_index: 0, write_index: 0, available: 0, } } pub fn push(&mut self, value: T) { self.data[self.write_index] = value; self.write_index = (self.write_index + 1) % self.data.len(); self.available = (self.available + 1).min(self.data.len()); } pub fn push_from_iter>(&mut self, iter: I) { let mut len = 0; for value in iter { self.data[self.write_index] = value; self.write_index = (self.write_index + 1) % self.data.len(); len += 1; } self.available = (self.available + len).min(self.data.len()); } pub fn chunks_exact_mut(&mut self, chunk_size: usize) -> ChunksExactMut { assert_eq!(self.read_index % chunk_size, 0); assert_eq!(self.data.len() % chunk_size, 0); ChunksExactMut { ringbuf: self, chunk_size, } } } pub struct ChunksExactMut<'a, T> { ringbuf: &'a mut RingBuf, chunk_size: usize, } impl<'a, T> Iterator for ChunksExactMut<'a, T> { type Item = &'a mut [T]; fn next(&mut self) -> Option { if self.ringbuf.available >= self.chunk_size { let read_index = self.ringbuf.read_index; self.ringbuf.read_index = (self.ringbuf.read_index + self.chunk_size) % self.ringbuf.data.len(); self.ringbuf.available -= self.chunk_size; let ret: &mut [T] = &mut self.ringbuf.data[read_index..read_index + self.chunk_size]; let ret: &'a mut [T] = unsafe { std::mem::transmute(ret) }; Some(ret) } else { None } } }