clippy fixes, tests

This commit is contained in:
Vinzenz Schroeter 2025-07-06 22:07:42 +02:00
parent c1b3c1ea06
commit ae72d1fd17
3 changed files with 93 additions and 38 deletions

View file

@ -180,6 +180,7 @@ impl Bitmap {
/// Creates a window into the bitmap. /// Creates a window into the bitmap.
/// ///
/// Returns None in case the window does not fit. /// Returns None in case the window does not fit.
#[must_use]
pub fn window( pub fn window(
&self, &self,
x: usize, x: usize,

View file

@ -311,6 +311,7 @@ impl<T: Value> ValueGrid<T> {
} }
} }
#[must_use]
/// Creates a window into the grid. /// Creates a window into the grid.
/// ///
/// Returns None in case the window does not fit. /// Returns None in case the window does not fit.

View file

@ -50,6 +50,7 @@ macro_rules! define_window {
}) })
} }
#[must_use]
/// Creates a window into the window. /// Creates a window into the window.
/// ///
/// Returns None in case the window does not fit. /// Returns None in case the window does not fit.
@ -66,6 +67,7 @@ macro_rules! define_window {
Window::new(self.grid, self.x + x, self.y + y, width, height) Window::new(self.grid, self.x + x, self.y + y, width, height)
} }
#[must_use]
pub fn split_horizontal( pub fn split_horizontal(
self, self,
left_width: usize, left_width: usize,
@ -73,17 +75,24 @@ macro_rules! define_window {
Window<'t, TElement, TGrid>, Window<'t, TElement, TGrid>,
Window<'t, TElement, TGrid>, Window<'t, TElement, TGrid>,
)> { )> {
let left = Window::new(self.grid, 0, 0, left_width, self.height)?; let left = Window::new(
self.grid,
self.x,
self.y,
left_width,
self.height,
)?;
let right = Window::new( let right = Window::new(
self.grid, self.grid,
left_width, self.x + left_width,
0, self.y,
self.width - left_width, self.width - left_width,
self.height, self.height,
)?; )?;
Some((left, right)) Some((left, right))
} }
#[must_use]
pub fn split_vertical( pub fn split_vertical(
self, self,
top_height: usize, top_height: usize,
@ -91,11 +100,13 @@ macro_rules! define_window {
Window<'t, TElement, TGrid>, Window<'t, TElement, TGrid>,
Window<'t, TElement, TGrid>, Window<'t, TElement, TGrid>,
)> { )> {
let top = Window::new(self.grid, 0, 0, self.width, top_height)?; let top = Window::new(
self.grid, self.x, self.y, self.width, top_height,
)?;
let bottom = Window::new( let bottom = Window::new(
self.grid, self.grid,
0, self.x,
top_height, self.y + top_height,
self.width, self.width,
self.height - top_height, self.height - top_height,
)?; )?;
@ -156,8 +167,8 @@ impl<TElement: Copy, TGrid: GridMut<TElement>> GridMut<TElement>
#[inherent::inherent] #[inherent::inherent]
impl<TGrid: GridMut<char>> CharGridMutExt for WindowMut<'_, char, TGrid> {} impl<TGrid: GridMut<char>> CharGridMutExt for WindowMut<'_, char, TGrid> {}
impl<'t, TElement: Copy, TGrid: GridMut<TElement>> impl<TElement: Copy, TGrid: GridMut<TElement>>
WindowMut<'t, TElement, TGrid> WindowMut<'_, TElement, TGrid>
{ {
/// Creates a mutable window into the grid. /// Creates a mutable window into the grid.
/// ///
@ -169,37 +180,56 @@ impl<'t, TElement: Copy, TGrid: GridMut<TElement>>
width: usize, width: usize,
height: usize, height: usize,
) -> Option<WindowMut<TElement, TGrid>> { ) -> Option<WindowMut<TElement, TGrid>> {
if x + width >= self.width || y + height >= self.height { if x + width > self.width || y + height > self.height {
return None; return None;
} }
WindowMut::new(self.grid, self.x + x, self.y + y, width, height) WindowMut::new(self.grid, self.x + x, self.y + y, width, height)
} }
pub fn deref_assign<O: Grid<TElement>>(&mut self, other: &O) {
assert!(self.width() == other.width());
assert!(self.height() == other.height());
for y in 0..self.height {
for x in 0..self.width {
self.set(x, y, other.get(x, y));
}
}
}
#[must_use]
pub fn split_horizontal_mut( pub fn split_horizontal_mut(
self, self,
left_width: usize, left_width: usize,
) -> Option<( ) -> Option<(Self, Self)> {
WindowMut<'t, TElement, TGrid>,
WindowMut<'t, TElement, TGrid>,
)> {
let (grid1, grid2) = unsafe { Self::duplicate_mutable_ref(self.grid) }; let (grid1, grid2) = unsafe { Self::duplicate_mutable_ref(self.grid) };
let left = WindowMut::new(grid1, 0, 0, left_width, self.height)?; let left =
let right = WindowMut::new(grid1, self.x, self.y, left_width, self.height)?;
WindowMut::new(grid2, left_width, 0, self.width - left_width, self.height)?; let right = WindowMut::new(
grid2,
self.x + left_width,
self.y,
self.width - left_width,
self.height,
)?;
Some((left, right)) Some((left, right))
} }
pub fn split_vertical_mut( #[must_use]
self, pub fn split_vertical_mut(self, top_height: usize) -> Option<(Self, Self)> {
top_height: usize,
) -> Option<(
WindowMut<'t, TElement, TGrid>,
WindowMut<'t, TElement, TGrid>,
)> {
let (grid1, grid2) = unsafe { Self::duplicate_mutable_ref(self.grid) }; let (grid1, grid2) = unsafe { Self::duplicate_mutable_ref(self.grid) };
let top = WindowMut::new(grid1, 0, 0, self.width, top_height)?; let top =
let bottom = WindowMut::new(grid1, self.x, self.y, self.width, top_height)?;
WindowMut::new(grid2, 0, top_height, self.width, self.height - top_height)?; let bottom = WindowMut::new(
grid2,
self.x,
self.y + top_height,
self.width,
self.height - top_height,
)?;
let foo = &mut [..];
*foo = [..];
Some((top, bottom)) Some((top, bottom))
} }
@ -214,11 +244,11 @@ impl<'t, TElement: Copy, TGrid: GridMut<TElement>>
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::containers::window::{Window, WindowMut}; use super::{Window, WindowMut};
use crate::{Bitmap, CharGrid, DataRef, GridMut}; use crate::{Bitmap, ByteGrid, CharGrid, DataRef, GridMut};
#[test] #[test]
fn test_grid_view_bitmap() { fn grid_view_bitmap() {
let mut bitmap = Bitmap::new(8, 4).unwrap(); let mut bitmap = Bitmap::new(8, 4).unwrap();
// non-byte-aligned views work // non-byte-aligned views work
@ -243,11 +273,11 @@ mod tests {
} }
#[test] #[test]
fn test_grid_view_char_grid() { fn grid_view_char_grid() {
let mut grid = CharGrid::new(3, 4); let mut grid = CharGrid::new(3, 4);
grid.fill(' '); grid.fill(' ');
let mut view = WindowMut::new(&mut grid, 1, 1, 1, 3).unwrap(); let mut view = grid.window_mut(1, 1, 1, 3).unwrap();
view.fill('#'); view.fill('#');
view.set(0, 0, '!'); view.set(0, 0, '!');
@ -257,22 +287,45 @@ mod tests {
); );
// full size view works // full size view works
_ = Window::new(&mut grid, 0, 0, 3, 4).unwrap(); _ = grid.window(0, 0, 3, 4).unwrap();
// zero size view does not work // zero size view does not work
assert!(Window::new(&mut grid, 1, 2, 2, 0).is_none()); assert!(grid.window(1, 2, 2, 0).is_none());
assert!(Window::new(&mut grid, 1, 2, 0, 1).is_none()); assert!(grid.window(1, 2, 0, 1).is_none());
} }
#[test] #[test]
fn round_trip_bitmap() { fn round_trip_bitmap() {
let mut bitmap = Bitmap::new(8, 4).unwrap(); let bitmap = Bitmap::new(8, 4).unwrap();
let non_aligned = Window::new(&mut bitmap, 3, 1, 4, 2).unwrap(); let non_aligned = bitmap.window(3, 1, 4, 2).unwrap();
assert_eq!(Bitmap::try_from(&non_aligned), Err(())); assert_eq!(Bitmap::try_from(&non_aligned), Err(()));
let aligned = Window::new(&mut bitmap, 0, 1, 8, 2).unwrap(); let aligned = bitmap.window(0, 1, 8, 2).unwrap();
assert!(matches!(Bitmap::try_from(&aligned), Ok(_))); assert!(matches!(Bitmap::try_from(&aligned), Ok(_)));
} }
#[test]
fn split_vertical() {
let grid = ByteGrid::new(5, 4);
let window = grid.window(0, 0, grid.width(), grid.height()).unwrap();
let (left, right) = window.split_vertical(3).unwrap();
assert_eq!(3, left.height());
assert_eq!(1, right.height());
assert_eq!(5, left.width());
assert_eq!(5, right.width())
}
#[test]
fn split_horizontal() {
let grid = ByteGrid::new(4, 5);
let window = grid.window(0, 0, grid.width(), grid.height()).unwrap();
let (top, bottom) = window.split_horizontal(3).unwrap();
assert_eq!(3, top.width());
assert_eq!(1, bottom.width());
assert_eq!(5, top.height());
assert_eq!(5, bottom.height())
}
} }