clippy + tests

This commit is contained in:
Jack Maguire 2023-04-17 21:51:43 +01:00 committed by Armin Becher
parent d0a7ee701a
commit cf0bcdf284

View file

@ -1,3 +1,5 @@
#![warn(clippy::all, clippy::pedantic)]
/*!
# Two Dimensional Grid
Continuous growable 2D data structure.
@ -195,7 +197,11 @@ impl<T> Grid<T> {
/// use grid::Grid;
/// Grid::from_vec(vec![1,2,3,4,5], 3);
/// ```
pub fn from_vec(vec: Vec<T>, cols: usize) -> Grid<T> {
///
/// # Panics
///
/// This can panic if the vector is empty, or if the vector length isn't a multiple of the number of columns.
#[must_use] pub fn from_vec(vec: Vec<T>, cols: usize) -> Grid<T> {
let rows = vec.len();
if rows == 0 {
if cols == 0 {
@ -266,17 +272,17 @@ impl<T> Grid<T> {
/// Returns the size of the gird as a two element tuple.
/// First element are the number of rows and the second the columns.
pub fn size(&self) -> (usize, usize) {
#[must_use] pub fn size(&self) -> (usize, usize) {
(self.rows, self.cols)
}
/// Returns the number of rows of the grid.
pub fn rows(&self) -> usize {
#[must_use] pub fn rows(&self) -> usize {
self.rows
}
/// Returns the number of columns of the grid.
pub fn cols(&self) -> usize {
#[must_use] pub fn cols(&self) -> usize {
self.cols
}
@ -287,7 +293,7 @@ impl<T> Grid<T> {
/// let grid : Grid<u8> = grid![];
/// assert!(grid.is_empty());
/// ```
pub fn is_empty(&self) -> bool {
#[must_use] pub fn is_empty(&self) -> bool {
self.data.is_empty()
}
@ -345,13 +351,12 @@ impl<T> Grid<T> {
pub fn iter_col(&self, col: usize) -> StepBy<Iter<T>> {
if col < self.cols {
return self.data[col..].iter().step_by(self.cols);
} else {
}
panic!(
"out of bounds. Column must be less than {:?}, but is {:?}.",
self.cols, col
)
}
}
/// Returns a mutable iterator over a column.
///
@ -374,13 +379,12 @@ impl<T> Grid<T> {
let cols = self.cols;
if col < cols {
return self.data[col..].iter_mut().step_by(cols);
} else {
}
panic!(
"out of bounds. Column must be less than {:?}, but is {:?}.",
self.cols, col
)
}
}
/// Returns an iterator over a row.
///
@ -467,17 +471,13 @@ impl<T> Grid<T> {
///
/// # Panics
///
/// Panics if the grid is not empty and `row.len() != grid.cols()`.
///
/// Also panics if `row.len() == 0`
/// Panics if:
/// - the grid is not empty and `row.len() != grid.cols()`
/// - `row.len() == 0`
pub fn push_row(&mut self, row: Vec<T>) {
assert_ne!(row.len(), 0);
if self.rows > 0 && row.len() != self.cols {
panic!(
"pushed row does not match. Length must be {:?}, but was {:?}.",
self.cols, row.len()
)
}
assert!(!(self.rows > 0 && row.len() != self.cols), "pushed row does not match. Length must be {:?}, but was {:?}.",
self.cols, row.len());
self.data.extend(row);
self.rows += 1;
if self.cols == 0{
@ -515,17 +515,13 @@ impl<T> Grid<T> {
///
/// # Panics
///
/// Panics if the grid is not empty and `col.len() != grid.rows()`.
///
/// Also panics if `col.len() == 0`
/// Panics if:
/// - the grid is not empty and `col.len() != grid.rows()`
/// - `col.len() == 0`
pub fn push_col(&mut self, col: Vec<T>) {
assert_ne!(col.len(), 0);
if self.cols > 0 && col.len() != self.rows {
panic!(
"pushed column does not match. Length must be {:?}, but was {:?}.",
self.rows, col.len()
)
}
assert!(!(self.cols > 0 && col.len() != self.rows), "pushed column does not match. Length must be {:?}, but was {:?}.",
self.rows, col.len());
self.data.extend(col);
for i in (1..self.rows).rev() {
let row_idx = i * self.cols;
@ -604,15 +600,13 @@ impl<T> Grid<T> {
///
/// # Panics
///
/// Panics if the grid is not empty and `row.len() != grid.cols()`.
/// Panics if:
/// - the grid is not empty and `row.len() != grid.cols()`.
/// - the index is greater than the number of rows
pub fn insert_row(&mut self, index: usize, row: Vec<T>) {
let input_len = row.len();
if self.cols > 0 && input_len != self.cols {
panic!("Inserted row must be of length {}, but was {}.", self.cols, row.len());
}
if index > self.rows {
panic!("Out of range. Index was {}, but must be less or equal to {}.", index, self.rows);
}
assert!(!(self.cols > 0 && input_len != self.cols), "Inserted row must be of length {}, but was {}.", self.cols, row.len());
assert!(index <= self.rows, "Out of range. Index was {}, but must be less or equal to {}.", index, self.rows);
let data_idx = index * input_len;
self.data.splice(data_idx..data_idx, row.into_iter());
self.cols = input_len;
@ -636,15 +630,13 @@ impl<T> Grid<T> {
///
/// # Panics
///
/// Panics if the grid is not empty and `col.len() != grid.rows()`.
/// Panics if:
/// - the grid is not empty and `col.len() != grid.rows()`.
/// - the index is greater than the number of columns
pub fn insert_col(&mut self, index: usize, col: Vec<T>) {
let input_len = col.len();
if self.rows > 0 && input_len != self.rows {
panic!("Inserted col must be of length {}, but was {}.", self.rows, col.len());
}
if index > self.cols {
panic!("Out of range. Index was {}, but must be less or equal to {}.", index, self.cols);
}
assert!(!(self.rows > 0 && input_len != self.rows), "Inserted col must be of length {}, but was {}.", self.rows, col.len());
assert!(index <= self.cols, "Out of range. Index was {}, but must be less or equal to {}.", index, self.cols);
for (row_iter, col_val) in col.into_iter().enumerate() {
let data_idx = row_iter * self.cols + index + row_iter;
self.data.insert(data_idx, col_val);
@ -665,17 +657,17 @@ impl<T> Grid<T> {
/// let flat = grid.flatten();
/// assert_eq!(flat, &vec![1,2,3,4,5,6]);
/// ```
pub fn flatten(&self) -> &Vec<T> {
#[must_use] pub fn flatten(&self) -> &Vec<T> {
&self.data
}
/// Converts self into a vector without clones or allocation.
pub fn into_vec(self) -> Vec<T> {
#[must_use] pub fn into_vec(self) -> Vec<T> {
self.data
}
/// Transpose the grid so that columns become rows in new grid.
pub fn transpose(&self) -> Grid<T>
#[must_use] pub fn transpose(&self) -> Grid<T>
where
T: Clone,
{
@ -707,7 +699,7 @@ impl<T> Grid<T> {
where
T: Clone
{
self.data.fill(value)
self.data.fill(value);
}
/// Fills the grid with elements returned by calling a closure repeatedly.
@ -732,13 +724,13 @@ impl<T> Grid<T> {
where
F: FnMut() -> T,
{
self.data.fill_with(f)
self.data.fill_with(f);
}
/// Iterate over the rows of the grid. Each time an iterator over a single
/// row is returned.
///
/// An item in this iterator is equal to a call to Grid.iter_row(row_index)
/// An item in this iterator is equal to a call to `Grid.iter_row(row_index)`
/// of the corresponding row.
///
/// # Examples
@ -749,14 +741,14 @@ impl<T> Grid<T> {
/// let sum_by_row: Vec<u8> = grid.iter_rows().map(|row| row.sum()).collect();
/// assert_eq!(sum_by_row, vec![1+2+3, 4+5+6])
/// ```
pub fn iter_rows(&self) -> GridRowIter<'_, T> {
#[must_use] pub fn iter_rows(&self) -> GridRowIter<'_, T> {
GridRowIter{grid: self, row_index: 0}
}
/// Iterate over the columns of the grid. Each time an iterator over a single
/// column is returned.
///
/// An item in this iterator is equal to a call to Grid.iter_col(col_index)
/// An item in this iterator is equal to a call to `Grid.iter_col(col_index)`
/// of the corresponding column.
///
/// # Examples
@ -767,7 +759,7 @@ impl<T> Grid<T> {
/// let sum_by_col: Vec<u8> = grid.iter_cols().map(|col| col.sum()).collect();
/// assert_eq!(sum_by_col, vec![1+4, 2+5, 3+6])
/// ```
pub fn iter_cols(&self) -> GridColIter<'_, T> {
#[must_use] pub fn iter_cols(&self) -> GridColIter<'_, T> {
GridColIter { grid: self, col_index: 0 }
}
}
@ -805,15 +797,17 @@ impl<T> Index<(usize, usize)> for Grid<T> {
type Output = T;
#[inline]
fn index(&self, (x, y): (usize, usize)) -> &T {
&self.data[y * self.cols + x]
fn index(&self, (row, col): (usize, usize)) -> &T {
assert!(!(row >= self.rows || col >= self.cols), "grid index out of bounds: ({row},{col}) out of ({},{})", self.rows, self.cols);
&self.data[row * self.cols + col]
}
}
impl<T> IndexMut<(usize, usize)> for Grid<T> {
#[inline]
fn index_mut(&mut self, (x, y): (usize, usize)) -> &mut T {
&mut self.data[y * self.cols + x]
fn index_mut(&mut self, (row, col): (usize, usize)) -> &mut T {
assert!(!(row >= self.rows || col >= self.cols), "grid index out of bounds: ({row},{col}) out of ({},{})", self.rows, self.cols);
&mut self.data[row * self.cols + col]
}
}
@ -823,7 +817,7 @@ impl<T: fmt::Debug> fmt::Debug for Grid<T> {
write!(f, "[");
if self.cols > 0 {
if f.alternate() {
write!(f, "\n");
writeln!(f);
/*
WARNING
@ -848,14 +842,14 @@ impl<T: fmt::Debug> fmt::Debug for Grid<T> {
write!(
f,
" {item:width$.precision$?}",
width = width,
precision = precision
// width = width,
// precision = precision
);
if row.peek().is_some() {
write!(f, ",");
}
}
write!(f, "]\n");
writeln!(f, "]");
}
} else {
for (i, _) in self.data.iter().enumerate().step_by(self.cols) {
@ -892,7 +886,7 @@ impl<'a, T> Iterator for GridRowIter<'a, T> {
let row_iter = self.grid.iter_row(row_index);
self.row_index += 1;
return Some(row_iter);
Some(row_iter)
}
}
@ -909,7 +903,7 @@ impl<'a, T> Iterator for GridColIter<'a, T> {
let row_iter = self.grid.iter_col(col_index);
self.col_index += 1;
return Some(row_iter);
Some(row_iter)
}
}
@ -929,7 +923,7 @@ mod test {
#[test]
fn from_vec_zero() {
let grid: Grid<u8> = Grid::from_vec(vec![], 0);
grid.is_empty();
let _ = grid.is_empty();
assert_eq!(grid.rows(), 0);
assert_eq!(grid.cols(), 0);
}
@ -1103,6 +1097,13 @@ mod test {
let _ = grid[0][5];
}
#[test]
#[should_panic]
fn idx_tup_out_of_col_bounds() {
let grid: Grid<char> = grid![['a', 'b', 'c', 'd']['a', 'b', 'c', 'd']['a', 'b', 'c', 'd']];
let _ = grid[(0, 5)];
}
#[test]
fn push_col_2x3() {
let mut grid: Grid<u8> = grid![
@ -1369,7 +1370,7 @@ r#"[
[ ( 80, 90), ( 5, 6)]
]"#;
assert_eq!(format!("{:#?}", grid), expected_output);
assert_eq!(format!("{grid:#?}"), expected_output);
let expected_output =
r#"[
@ -1552,6 +1553,15 @@ r#"[
assert_eq!(grid[1][1], 4);
}
#[test]
fn idx_tup() {
let grid: Grid<u8> = Grid::from_vec(vec![1, 2, 3, 4], 2);
assert_eq!(grid[(0,0)], 1);
assert_eq!(grid[(0,1)], 2);
assert_eq!(grid[(1,0)], 3);
assert_eq!(grid[(1,1)], 4);
}
#[test]
#[should_panic]
fn idx_panic_1() {
@ -1559,6 +1569,13 @@ r#"[
let _ = grid[20][0];
}
#[test]
#[should_panic]
fn idx_tup_panic_1() {
let grid = Grid::init(1, 2, 3);
let _ = grid[(20, 0)];
}
#[test]
#[should_panic]
fn idx_panic_2() {
@ -1566,6 +1583,13 @@ r#"[
let _ = grid[0][20];
}
#[test]
#[should_panic]
fn idx_tup_panic_2() {
let grid = Grid::init(1, 2, 3);
let _ = grid[(0, 20)];
}
#[test]
fn idx_set() {
let mut grid = Grid::init(1, 2, 3);
@ -1573,6 +1597,13 @@ r#"[
assert_eq!(grid[0][0], 4);
}
#[test]
fn idx_tup_set() {
let mut grid = Grid::init(1, 2, 3);
grid[(0,0)] = 4;
assert_eq!(grid[(0, 0)], 4);
}
#[test]
fn size() {
let grid = Grid::init(1, 2, 3);
@ -1606,13 +1637,12 @@ r#"[
let grid: Grid<u8> = grid![[1,2,3][4,5,6]];
let max_by_row: Vec<u8> = grid
.iter_rows()
.map(|row| row.max().unwrap())
.map(|item| *item)
.map(|row| row.max().unwrap()).copied()
.collect();
assert_eq!(max_by_row, vec![3, 6]);
let sum_by_row: Vec<u8> = grid.iter_rows().map(|row| row.sum()).collect();
assert_eq!(sum_by_row, vec![1+2+3, 4+5+6])
assert_eq!(sum_by_row, vec![1+2+3, 4+5+6]);
}
#[test]
@ -1620,13 +1650,12 @@ r#"[
let grid: Grid<u8> = grid![[1,2,3][4,5,6]];
let max_by_col: Vec<u8> = grid
.iter_cols()
.map(|col| col.max().unwrap())
.map(|item| *item)
.map(|col| col.max().unwrap()).copied()
.collect();
assert_eq!(max_by_col, vec![4,5,6]);
let sum_by_col: Vec<u8> = grid.iter_cols().map(|col| col.sum()).collect();
assert_eq!(sum_by_col, vec![1+4, 2+5, 3+6])
assert_eq!(sum_by_col, vec![1+4, 2+5, 3+6]);
}
}