From 9bf4b22cb1b97827a67336c1d2add77e50d5ad30 Mon Sep 17 00:00:00 2001 From: Andrew Golovashevich Date: Tue, 10 Mar 2026 20:04:44 +0300 Subject: [PATCH] Index access for cycled buffer --- data/src/cycled_buffer.rs | 62 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/data/src/cycled_buffer.rs b/data/src/cycled_buffer.rs index f4a3c2d..261b8e8 100644 --- a/data/src/cycled_buffer.rs +++ b/data/src/cycled_buffer.rs @@ -1,5 +1,5 @@ use std::mem::ManuallyDrop; -use std::ops::{Deref, DerefMut, IndexMut}; +use std::ops::{Deref, DerefMut, Index, IndexMut}; use std::ptr::NonNull; pub(crate) struct CycledBuffer { @@ -78,6 +78,58 @@ impl CycledBuffer { } } +impl Index for CycledBuffer { + type Output = T; + + fn index(&self, index: usize) -> &Self::Output { + match self.pos { + BufferState::Filling { .. } => { + if index < self.data.len() { + &self.data[self.data.len() - 1 - index] + } else { + panic!("Index out of range") + } + } + BufferState::Cycle { next_write_pos } => { + if index < next_write_pos { + return &self.data[next_write_pos - 1 - index]; + } else { + if index >= self.data.len() { + panic!("Index out of range"); + } + return &self.data[self.data.len() - 1 - (index - next_write_pos)]; + } + } + BufferState::Empty => panic!("Index out of range"), + } + } +} + +impl IndexMut for CycledBuffer { + fn index_mut(&mut self, index: usize) -> &mut Self::Output { + let data_len = self.data.len(); + match self.pos { + BufferState::Filling { .. } => { + if index < self.data.len() { + &mut self.data[data_len - 1 - index] + } else { + panic!("Index out of range") + } + } + BufferState::Cycle { next_write_pos } => { + if index < next_write_pos { + return &mut self.data[next_write_pos - 1 - index]; + } else { + if index >= self.data.len() { + panic!("Index out of range"); + } + return &mut self.data[data_len - 1 - (index - next_write_pos)]; + } + } + BufferState::Empty => panic!("Index out of range"), + } + } +} /* impl Drop for CycledBuffer { @@ -182,7 +234,7 @@ impl E> Iterator for CycledIterator } else { self.state = IteratorState::Done; } - return Some(e) + return Some(e); } } } @@ -202,6 +254,9 @@ mod _tests { assert_eq!(it.next(), Some(&9)); assert_eq!(it.next(), Some(&6)); assert_eq!(it.next(), None); + + assert_eq!(b[0], 9); + assert_eq!(b[1], 6); } #[test] fn test2() { @@ -214,5 +269,8 @@ mod _tests { assert_eq!(it.next(), Some(&2)); assert_eq!(it.next(), Some(&5)); assert_eq!(it.next(), None); + + assert_eq!(b[0], 2); + assert_eq!(b[1], 5); } }