From b08fd9706639920bc89fa4536a766441b26ff225 Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Wed, 5 Jun 2024 20:14:05 +0200 Subject: [PATCH] more tests, move stuff --- crates/servicepoint/src/byte_grid.rs | 88 ++++++++++++++------------- crates/servicepoint/src/grid.rs | 59 ++++++------------ crates/servicepoint/src/lib.rs | 7 ++- crates/servicepoint/src/pixel_grid.rs | 47 ++++++++------ 4 files changed, 95 insertions(+), 106 deletions(-) diff --git a/crates/servicepoint/src/byte_grid.rs b/crates/servicepoint/src/byte_grid.rs index c9f8a63..1912bb3 100644 --- a/crates/servicepoint/src/byte_grid.rs +++ b/crates/servicepoint/src/byte_grid.rs @@ -1,6 +1,5 @@ use std::slice::{Iter, IterMut}; -use crate::grid::RefGrid; use crate::{DataRef, Grid}; /// A 2D grid of bytes @@ -53,7 +52,7 @@ impl ByteGrid { /// # let grid = ByteGrid::new(2,2); /// for y in 0..grid.height() { /// for x in 0..grid.width() { - /// grid.get(x, y) + /// grid.get(x, y); /// } /// } /// ``` @@ -76,17 +75,37 @@ impl ByteGrid { self.data.iter_mut() } - fn check_indexes(&self, x: usize, y: usize) { - assert!( - x < self.width, - "cannot access byte {x}-{y} because x is outside of bounds 0..{}", - self.width - ); - assert!( - y < self.height, - "cannot access byte {x}-{y} because y is outside of bounds 0..{}", - self.height - ); + /// Get a mutable reference to the current value at the specified position. + /// + /// # Arguments + /// + /// * `x` and `y`: position of the cell + /// + /// # Panics + /// + /// When accessing `x` or `y` out of bounds. + pub fn get_ref_mut(&mut self, x: usize, y: usize) -> &mut u8 { + self.assert_in_bounds(x, y); + &mut self.data[x + y * self.width] + } + + /// Get a mutable reference to the current value at the specified position if position is in bounds. + /// + /// # Arguments + /// + /// * `x` and `y`: position of the cell + /// + /// returns: Reference to cell or None + pub fn get_ref_mut_optional( + &mut self, + x: isize, + y: isize, + ) -> Option<&mut u8> { + if self.is_in_bounds(x, y) { + Some(&mut self.data[x as usize + y as usize * self.width]) + } else { + None + } } } @@ -102,7 +121,7 @@ impl Grid for ByteGrid { /// /// When accessing `x` or `y` out of bounds. fn set(&mut self, x: usize, y: usize, value: u8) { - self.check_indexes(x, y); + self.assert_in_bounds(x, y); self.data[x + y * self.width] = value; } @@ -116,7 +135,7 @@ impl Grid for ByteGrid { /// /// When accessing `x` or `y` out of bounds. fn get(&self, x: usize, y: usize) -> u8 { - self.check_indexes(x, y); + self.assert_in_bounds(x, y); self.data[x + y * self.width] } @@ -152,34 +171,6 @@ impl From for Vec { } } -impl RefGrid for ByteGrid { - fn get_ref(&self, x: usize, y: usize) -> &u8 { - self.check_indexes(x, y); - &self.data[x + y * self.width] - } - - fn get_ref_optional(&self, x: isize, y: isize) -> Option<&u8> { - if self.is_in_bounds(x, y) { - Some(&self.data[x as usize + y as usize * self.width]) - } else { - None - } - } - - fn get_ref_mut(&mut self, x: usize, y: usize) -> &mut u8 { - self.check_indexes(x, y); - &mut self.data[x + y * self.width] - } - - fn get_ref_mut_optional(&mut self, x: isize, y: isize) -> Option<&mut u8> { - if self.is_in_bounds(x, y) { - Some(&mut self.data[x as usize + y as usize * self.width]) - } else { - None - } - } -} - pub struct IterRows<'t> { byte_grid: &'t ByteGrid, row: usize, @@ -302,4 +293,15 @@ mod tests { let vec = ByteGrid::load(2, 2, &[0, 1, 2, 3]); vec.get(1, 2); } + + #[test] + fn ref_mut() { + let mut vec = ByteGrid::load(2, 2, &[0, 1, 2, 3]); + + let top_left = vec.get_ref_mut(0, 0); + *top_left += 5; + + assert_eq!(None, vec.get_ref_mut_optional(2, 2)); + assert_eq!(Some(&mut 5), vec.get_ref_mut_optional(0, 0)); + } } diff --git a/crates/servicepoint/src/grid.rs b/crates/servicepoint/src/grid.rs index 882f678..7e71532 100644 --- a/crates/servicepoint/src/grid.rs +++ b/crates/servicepoint/src/grid.rs @@ -62,54 +62,29 @@ pub trait Grid { /// the height in y-direction fn height(&self) -> usize; - /// Checks whether the specified position is + /// Checks whether the specified signed position is in grid bounds fn is_in_bounds(&self, x: isize, y: isize) -> bool { - x > 0 + x >= 0 && x < self.width() as isize - && y > 0 + && y >= 0 && y < self.height() as isize } -} -/// A grid that can return cells as references. -pub trait RefGrid { - /// Get a reference to the current value at the specified position - /// - /// # Arguments - /// - /// * `x` and `y`: position of the cell + /// Asserts that the specified unsigned position is in grid bounds. /// /// # Panics /// - /// When accessing `x` or `y` out of bounds. - fn get_ref(&self, x: usize, y: usize) -> &T; - - /// Get a reference to the current value at the specified position if the position is in bounds. - /// - /// # Arguments - /// - /// * `x` and `y`: position of the cell - /// - /// returns: Reference to cell or None - fn get_ref_optional(&self, x: isize, y: isize) -> Option<&T>; - - /// Get a mutable reference to the current value at the specified position - /// - /// # Arguments - /// - /// * `x` and `y`: position of the cell - /// - /// # Panics - /// - /// When accessing `x` or `y` out of bounds. - fn get_ref_mut(&mut self, x: usize, y: usize) -> &mut T; - - /// Get a mutable reference to the current value at the specified position if position is in bounds. - /// - /// # Arguments - /// - /// * `x` and `y`: position of the cell - /// - /// returns: Reference to cell or None - fn get_ref_mut_optional(&mut self, x: isize, y: isize) -> Option<&mut T>; + /// When the specified position is out of bounds for this grid. + fn assert_in_bounds(&self, x: usize, y: usize) { + assert!( + x < self.width(), + "cannot access index [{x}, {y}] because x is outside of bounds 0..{}", + self.width() + ); + assert!( + y < self.height(), + "cannot access byte [{x}, {y}] because y is outside of bounds 0..{}", + self.height() + ); + } } diff --git a/crates/servicepoint/src/lib.rs b/crates/servicepoint/src/lib.rs index dd03d96..dcb2755 100644 --- a/crates/servicepoint/src/lib.rs +++ b/crates/servicepoint/src/lib.rs @@ -2,16 +2,17 @@ use std::time::Duration; +pub use bitvec; +use bitvec::prelude::{BitVec, Msb0}; + pub use crate::byte_grid::ByteGrid; pub use crate::command::{Brightness, Command, Offset, Origin}; pub use crate::compression_code::CompressionCode; pub use crate::connection::Connection; pub use crate::data_ref::DataRef; -pub use crate::grid::{Grid, RefGrid}; +pub use crate::grid::Grid; pub use crate::packet::{Header, Packet, Payload}; pub use crate::pixel_grid::PixelGrid; -pub use bitvec; -use bitvec::prelude::{BitVec, Msb0}; type SpBitVec = BitVec; diff --git a/crates/servicepoint/src/pixel_grid.rs b/crates/servicepoint/src/pixel_grid.rs index bb8d4c2..f078a00 100644 --- a/crates/servicepoint/src/pixel_grid.rs +++ b/crates/servicepoint/src/pixel_grid.rs @@ -1,6 +1,5 @@ use bitvec::order::Msb0; use bitvec::prelude::BitSlice; -use bitvec::ptr::Mutability; use bitvec::slice::IterMut; use crate::{BitVec, DataRef, Grid, SpBitVec, PIXEL_HEIGHT, PIXEL_WIDTH}; @@ -73,7 +72,7 @@ impl PixelGrid { /// # let grid = PixelGrid::new(8,2); /// for y in 0..grid.height() { /// for x in 0..grid.width() { - /// grid.get(x, y) + /// grid.get(x, y); /// } /// } /// ``` @@ -90,7 +89,7 @@ impl PixelGrid { /// # let value = false; /// for y in 0..grid.height() { /// for x in 0..grid.width() { - /// grid.set(x, y, value) + /// grid.set(x, y, value); /// } /// } /// ``` @@ -115,19 +114,6 @@ impl PixelGrid { row: 0, } } - - fn check_indexes(&self, x: usize, y: usize) { - assert!( - x < self.width, - "cannot access pixel {x}-{y} because x is outside of bounds 0..{}", - self.width - ); - assert!( - y < self.height, - "cannot access pixel {x}-{y} because y is outside of bounds 0..{}", - self.height - ); - } } impl Grid for PixelGrid { @@ -144,12 +130,12 @@ impl Grid for PixelGrid { /// /// When accessing `x` or `y` out of bounds. fn set(&mut self, x: usize, y: usize, value: bool) { - self.check_indexes(x, y); + self.assert_in_bounds(x, y); self.bit_vec.set(x + y * self.width, value) } fn get(&self, x: usize, y: usize) -> bool { - self.check_indexes(x, y); + self.assert_in_bounds(x, y); self.bit_vec[x + y * self.width] } @@ -270,4 +256,29 @@ mod tests { let mut vec = PixelGrid::new(8, 2); vec.set(1, 2, false); } + + #[test] + fn iter() { + let grid = PixelGrid::new(8, 2); + assert_eq!(16, grid.iter().count()) + } + + #[test] + fn iter_rows() { + let grid = PixelGrid::load(8, 2, &[0x04, 0x40]); + let mut iter = grid.iter_rows(); + + assert_eq!(iter.next().unwrap().count_ones(), 1); + assert_eq!(iter.next().unwrap().count_ones(), 1); + assert_eq!(None, iter.next()); + } + + #[test] + fn iter_mut() { + let mut grid = PixelGrid::new(8, 2); + for (index, mut pixel) in grid.iter_mut().enumerate() { + pixel.set(index % 2 == 0); + } + assert_eq!(grid.data_ref(), [0xAA, 0xAA]); + } }