river_ring_buffer/
lib.rs

1use std::fmt;
2
3#[derive(Debug, Clone, PartialEq, Eq)]
4pub struct BufferFullError;
5
6impl fmt::Display for BufferFullError {
7    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8        write!(f, "Buffer full")
9    }
10}
11
12type Result<T> = std::result::Result<T, BufferFullError>;
13
14pub struct RingBuffer<T> {
15    buffer: Vec<T>,
16    write_index: usize,
17    read_index: usize,
18    capacity: usize,
19}
20
21impl<T> RingBuffer<T>
22where
23    T: Default,
24    T: Copy,
25{
26    /// Create a new ring buffer with the given capacity
27    pub fn new(capacity: usize) -> Self {
28        RingBuffer {
29            capacity: capacity + 1,
30            buffer: vec![T::default(); capacity + 1],
31            write_index: 0,
32            read_index: 0,
33        }
34    }
35
36    /// Read a value from the buffer
37    ///
38    /// Returns `None` if the buffer is empty.
39    pub fn read(&mut self) -> Option<T> {
40        if self.read_index == self.write_index {
41            return None;
42        }
43
44        let value = self.buffer[self.read_index];
45        self.read_index = (self.read_index + 1) % self.buffer.len();
46
47        Some(value)
48    }
49
50    /// Write a value to the buffer
51    ///
52    /// If the buffer is full an error is returned.
53    pub fn put(&mut self, arg: T) -> Result<()> {
54        if (self.write_index + 1) % self.capacity == self.read_index {
55            return Err(BufferFullError);
56        }
57
58        self.buffer[self.write_index] = arg;
59        self.write_index = (self.write_index + 1) % self.capacity;
60        Ok(())
61    }
62}
63
64#[cfg(test)]
65mod tests {
66    use super::*;
67
68    #[test]
69    fn it_returns_none_when_ring_buffer_empty() {
70        let mut buffer: RingBuffer<i32> = RingBuffer::new(10); // Allocate a new ring buffer with capacity 10
71
72        assert_eq!(None, buffer.read()); // Read from the buffer
73    }
74
75    #[test]
76    fn it_returns_values_in_fifo_order() -> Result<()> {
77        let mut buffer = RingBuffer::new(10);
78
79        buffer.put(1)?;
80        buffer.put(2)?;
81        buffer.put(3)?;
82        buffer.put(4)?;
83        buffer.put(5)?;
84
85        assert_eq!(Some(1), buffer.read());
86        assert_eq!(Some(2), buffer.read());
87        assert_eq!(Some(3), buffer.read());
88        assert_eq!(Some(4), buffer.read());
89        assert_eq!(Some(5), buffer.read());
90
91        Ok(())
92    }
93
94    #[test]
95    fn it_returns_error_when_buffer_is_full() {
96        let mut buffer = RingBuffer::new(3);
97
98        buffer.put(1).unwrap();
99        buffer.put(2).unwrap();
100        buffer.put(3).unwrap();
101
102        assert_eq!(Err(BufferFullError), buffer.put(4));
103    }
104
105    #[test]
106    fn it_overwrites_oldest_value_when_buffer_is_full() -> Result<()> {
107        let mut buffer = RingBuffer::new(3);
108
109        buffer.put(1)?;
110        buffer.put(2)?;
111        buffer.put(3)?;
112
113        assert_eq!(Some(1), buffer.read());
114
115        buffer.put(4)?;
116
117        assert_eq!(Some(2), buffer.read());
118        assert_eq!(Some(3), buffer.read());
119        assert_eq!(Some(4), buffer.read());
120
121        Ok(())
122    }
123}