diff --git a/README.md b/README.md index de9db76..1b0c429 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Yet another Rust ring buffer implementation. Features: * Checked/unchecked element/iterator safe push -* Mutable exact chunk iterator (read contiguous slices) +* Mutable/immutable exact chunk iterator (read contiguous slices) ## License diff --git a/src/lib.rs b/src/lib.rs index ec44407..40d782d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -64,6 +64,16 @@ impl RingBuf { len } + pub fn chunks_exact(&mut self, chunk_size: usize) -> ChunksExact { + assert_eq!(self.read_index % chunk_size, 0); + assert_eq!(self.data.len() % chunk_size, 0); + + ChunksExact { + ringbuf: self, + chunk_size, + } + } + 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); @@ -75,6 +85,28 @@ impl RingBuf { } } +pub struct ChunksExact<'a, T> { + ringbuf: &'a mut RingBuf, + chunk_size: usize, +} + +impl<'a, T> Iterator for ChunksExact<'a, T> { + type Item = &'a [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: &[T] = &self.ringbuf.data[read_index..read_index + self.chunk_size]; + let ret: &'a [T] = unsafe { std::mem::transmute(ret) }; + Some(ret) + } else { + None + } + } +} + pub struct ChunksExactMut<'a, T> { ringbuf: &'a mut RingBuf, chunk_size: usize,