max7219_display/led_matrix/
buffer.rs

1//! Matrix buffer for LED matrix operations
2
3use crate::{Error, Result};
4
5/// 8x8 matrix buffer for LED matrix displays
6#[derive(Debug, Clone)]
7pub struct MatrixBuffer {
8    data: [u8; 8],
9}
10
11impl MatrixBuffer {
12    /// Create a new empty buffer
13    pub const fn new() -> Self {
14        Self { data: [0; 8] }
15    }
16
17    /// Create a buffer from raw data
18    pub const fn from_data(data: [u8; 8]) -> Self {
19        Self { data }
20    }
21
22    /// Get reference to buffer data
23    pub fn data(&self) -> &[u8; 8] {
24        &self.data
25    }
26
27    /// Get mutable reference to buffer data
28    pub fn data_mut(&mut self) -> &mut [u8; 8] {
29        &mut self.data
30    }
31
32    /// Set a pixel in the buffer
33    pub fn set_pixel(&mut self, x: u8, y: u8, state: bool) -> Result<()> {
34        if x >= 8 || y >= 8 {
35            return Err(Error::BufferError);
36        }
37
38        let bit_mask = 1 << x;
39        if state {
40            self.data[y as usize] |= bit_mask;
41        } else {
42            self.data[y as usize] &= !bit_mask;
43        }
44
45        Ok(())
46    }
47
48    /// Get pixel state from buffer
49    pub fn get_pixel(&self, x: u8, y: u8) -> Result<bool> {
50        if x >= 8 || y >= 8 {
51            return Err(Error::BufferError);
52        }
53
54        let bit_mask = 1 << x;
55        Ok((self.data[y as usize] & bit_mask) != 0)
56    }
57
58    /// Clear the entire buffer
59    pub fn clear(&mut self) {
60        self.data = [0; 8];
61    }
62
63    /// Fill the entire buffer
64    pub fn fill(&mut self) {
65        self.data = [0xFF; 8];
66    }
67
68    /// Set a row in the buffer
69    pub fn set_row(&mut self, row: u8, data: u8) -> Result<()> {
70        if row >= 8 {
71            return Err(Error::BufferError);
72        }
73
74        self.data[row as usize] = data;
75        Ok(())
76    }
77
78    /// Get a row from the buffer
79    pub fn get_row(&self, row: u8) -> Result<u8> {
80        if row >= 8 {
81            return Err(Error::BufferError);
82        }
83
84        Ok(self.data[row as usize])
85    }
86}
87
88impl Default for MatrixBuffer {
89    fn default() -> Self {
90        Self::new()
91    }
92}
93
94#[cfg(test)]
95mod tests {
96    use super::*;
97
98    #[test]
99    fn test_new_buffer() {
100        let buffer = MatrixBuffer::new();
101        assert_eq!(buffer.data(), &[0; 8]);
102    }
103
104    #[test]
105    fn test_default_buffer() {
106        let buffer: MatrixBuffer = Default::default();
107        assert_eq!(buffer.data(), &[0; 8]);
108    }
109
110    #[test]
111    fn test_from_data() {
112        let data = [0xFF, 0x00, 0xAA, 0x55, 0xF0, 0x0F, 0xCC, 0x33];
113        let buffer = MatrixBuffer::from_data(data);
114        assert_eq!(buffer.data(), &data);
115    }
116
117    #[test]
118    fn test_clear() {
119        let mut buffer = MatrixBuffer::from_data([0xFF; 8]);
120        buffer.clear();
121        assert_eq!(buffer.data(), &[0; 8]);
122    }
123
124    #[test]
125    fn test_fill() {
126        let mut buffer = MatrixBuffer::new();
127        buffer.fill();
128        assert_eq!(buffer.data(), &[0xFF; 8]);
129    }
130
131    #[test]
132    fn test_set_pixel_valid() {
133        let mut buffer = MatrixBuffer::new();
134
135        // Set some pixels
136        assert!(buffer.set_pixel(0, 0, true).is_ok());
137        assert!(buffer.set_pixel(7, 7, true).is_ok());
138        assert!(buffer.set_pixel(3, 4, true).is_ok());
139
140        // Check pixel states
141        assert!(buffer.get_pixel(0, 0).unwrap());
142        assert!(buffer.get_pixel(7, 7).unwrap());
143        assert!(buffer.get_pixel(3, 4).unwrap());
144        assert!(!buffer.get_pixel(1, 1).unwrap());
145    }
146
147    #[test]
148    fn test_set_pixel_invalid() {
149        let mut buffer = MatrixBuffer::new();
150
151        // Test invalid coordinates
152        assert_eq!(buffer.set_pixel(8, 0, true), Err(Error::BufferError));
153        assert_eq!(buffer.set_pixel(0, 8, true), Err(Error::BufferError));
154        assert_eq!(buffer.set_pixel(255, 0, true), Err(Error::BufferError));
155        assert_eq!(buffer.set_pixel(0, 255, true), Err(Error::BufferError));
156    }
157
158    #[test]
159    fn test_get_pixel_invalid() {
160        let buffer = MatrixBuffer::new();
161
162        // Test invalid coordinates
163        assert_eq!(buffer.get_pixel(8, 0), Err(Error::BufferError));
164        assert_eq!(buffer.get_pixel(0, 8), Err(Error::BufferError));
165        assert_eq!(buffer.get_pixel(255, 0), Err(Error::BufferError));
166        assert_eq!(buffer.get_pixel(0, 255), Err(Error::BufferError));
167    }
168
169    #[test]
170    fn test_pixel_manipulation() {
171        let mut buffer = MatrixBuffer::new();
172
173        // Set a pixel
174        buffer.set_pixel(2, 3, true).unwrap();
175        assert!(buffer.get_pixel(2, 3).unwrap());
176
177        // Clear the same pixel
178        buffer.set_pixel(2, 3, false).unwrap();
179        assert!(!buffer.get_pixel(2, 3).unwrap());
180
181        // Test bit manipulation doesn't affect other bits
182        buffer.set_pixel(0, 0, true).unwrap();
183        buffer.set_pixel(7, 0, true).unwrap();
184        assert!(buffer.get_pixel(0, 0).unwrap());
185        assert!(buffer.get_pixel(7, 0).unwrap());
186        assert!(!buffer.get_pixel(1, 0).unwrap());
187        assert!(!buffer.get_pixel(6, 0).unwrap());
188    }
189
190    #[test]
191    fn test_set_row_valid() {
192        let mut buffer = MatrixBuffer::new();
193
194        // Set rows with different values
195        assert!(buffer.set_row(0, 0xFF).is_ok());
196        assert!(buffer.set_row(7, 0x00).is_ok());
197        assert!(buffer.set_row(3, 0xAA).is_ok());
198
199        // Verify row values
200        assert_eq!(buffer.get_row(0).unwrap(), 0xFF);
201        assert_eq!(buffer.get_row(7).unwrap(), 0x00);
202        assert_eq!(buffer.get_row(3).unwrap(), 0xAA);
203    }
204
205    #[test]
206    fn test_set_row_invalid() {
207        let mut buffer = MatrixBuffer::new();
208
209        // Test invalid row indices
210        assert_eq!(buffer.set_row(8, 0xFF), Err(Error::BufferError));
211        assert_eq!(buffer.set_row(255, 0xFF), Err(Error::BufferError));
212    }
213
214    #[test]
215    fn test_get_row_invalid() {
216        let buffer = MatrixBuffer::new();
217
218        // Test invalid row indices
219        assert_eq!(buffer.get_row(8), Err(Error::BufferError));
220        assert_eq!(buffer.get_row(255), Err(Error::BufferError));
221    }
222
223    #[test]
224    fn test_data_mut() {
225        let mut buffer = MatrixBuffer::new();
226        let data_mut = buffer.data_mut();
227
228        // Modify the buffer through the mutable reference
229        data_mut[0] = 0b10101010;
230        data_mut[1] = 0b01010101;
231
232        // Confirm that the internal data was updated
233        assert_eq!(buffer.data()[0], 0b10101010);
234        assert_eq!(buffer.data()[1], 0b01010101);
235    }
236}