err returns for series methods
This commit is contained in:
		
							parent
							
								
									7a23fcb54b
								
							
						
					
					
						commit
						98901f4479
					
				
					 5 changed files with 89 additions and 30 deletions
				
			
		|  | @ -12,3 +12,6 @@ version = "0.10.0" | |||
| 
 | ||||
| [workspace.lints.rust] | ||||
| missing-docs = "warn" | ||||
| 
 | ||||
| [workspace.dependencies] | ||||
| thiserror = "1.0.69" | ||||
|  |  | |||
|  | @ -22,6 +22,7 @@ rust-lzma = { version = "0.6.0", optional = true } | |||
| rand = { version = "0.8", optional = true } | ||||
| tungstenite = { version = "0.24.0", optional = true } | ||||
| once_cell = { version = "1.20.2", optional = true } | ||||
| thiserror.workspace = true | ||||
| 
 | ||||
| [features] | ||||
| default = ["compression_lzma", "protocol_udp", "cp437"] | ||||
|  |  | |||
|  | @ -1,3 +1,4 @@ | |||
| use crate::primitive_grid::SeriesError; | ||||
| use crate::PrimitiveGrid; | ||||
| 
 | ||||
| /// A grid containing UTF-8 characters.
 | ||||
|  | @ -20,15 +21,23 @@ impl CharGrid { | |||
| 
 | ||||
|     /// Overwrites a row in the grid with a str.
 | ||||
|     ///
 | ||||
|     /// Returns [None] if y is out of bounds or `row` is not of the correct size.
 | ||||
|     pub fn set_row_str(&mut self, y: usize, value: &str) -> Option<()> { | ||||
|     /// Returns [SeriesError] if y is out of bounds or `row` is not of the correct size.
 | ||||
|     pub fn set_row_str( | ||||
|         &mut self, | ||||
|         y: usize, | ||||
|         value: &str, | ||||
|     ) -> Result<(), SeriesError> { | ||||
|         self.set_row(y, value.chars().collect::<Vec<_>>().as_ref()) | ||||
|     } | ||||
| 
 | ||||
|     /// Overwrites a column in the grid with a str.
 | ||||
|     ///
 | ||||
|     /// Returns [None] if y is out of bounds or `row` is not of the correct size.
 | ||||
|     pub fn set_col_str(&mut self, x: usize, value: &str) -> Option<()> { | ||||
|     /// Returns [SeriesError] if y is out of bounds or `row` is not of the correct size.
 | ||||
|     pub fn set_col_str( | ||||
|         &mut self, | ||||
|         x: usize, | ||||
|         value: &str, | ||||
|     ) -> Result<(), SeriesError> { | ||||
|         self.set_col(x, value.chars().collect::<Vec<_>>().as_ref()) | ||||
|     } | ||||
| } | ||||
|  | @ -41,7 +50,7 @@ mod test { | |||
|         let mut grid = CharGrid::new(2, 3); | ||||
|         assert_eq!(grid.get_col_str(2), None); | ||||
|         assert_eq!(grid.get_col_str(1), Some(String::from("\0\0\0"))); | ||||
|         assert_eq!(grid.set_col_str(1, "abc"), Some(())); | ||||
|         assert_eq!(grid.set_col_str(1, "abc"), Ok(())); | ||||
|         assert_eq!(grid.get_col_str(1), Some(String::from("abc"))); | ||||
|     } | ||||
| 
 | ||||
|  | @ -50,8 +59,14 @@ mod test { | |||
|         let mut grid = CharGrid::new(2, 3); | ||||
|         assert_eq!(grid.get_row_str(3), None); | ||||
|         assert_eq!(grid.get_row_str(1), Some(String::from("\0\0"))); | ||||
|         assert_eq!(grid.set_row_str(1, "abc"), None); | ||||
|         assert_eq!(grid.set_row_str(1, "ab"), Some(())); | ||||
|         assert_eq!( | ||||
|             grid.set_row_str(1, "abc"), | ||||
|             Err(SeriesError::InvalidLength { | ||||
|                 expected: 2, | ||||
|                 actual: 3 | ||||
|             }) | ||||
|         ); | ||||
|         assert_eq!(grid.set_row_str(1, "ab"), Ok(())); | ||||
|         assert_eq!(grid.get_row_str(1), Some(String::from("ab"))); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -49,7 +49,7 @@ pub use crate::cp437::Cp437Grid; | |||
| pub use crate::data_ref::DataRef; | ||||
| pub use crate::grid::Grid; | ||||
| pub use crate::origin::{Origin, Pixels, Tiles}; | ||||
| pub use crate::primitive_grid::PrimitiveGrid; | ||||
| pub use crate::primitive_grid::{PrimitiveGrid, SeriesError}; | ||||
| 
 | ||||
| /// An alias for the specific type of [bitvec::prelude::BitVec] used.
 | ||||
| pub type BitVec = bitvec::prelude::BitVec<u8, bitvec::prelude::Msb0>; | ||||
|  |  | |||
|  | @ -13,6 +13,14 @@ pub struct PrimitiveGrid<T: PrimitiveGridType> { | |||
|     data: Vec<T>, | ||||
| } | ||||
| 
 | ||||
| #[derive(thiserror::Error, Debug, PartialEq)] | ||||
| pub enum SeriesError { | ||||
|     #[error("The index {index} was out of bounds for size {size}")] | ||||
|     OutOfBounds { index: usize, size: usize }, | ||||
|     #[error("The provided series was expected to have a length of {expected}, but was {actual}")] | ||||
|     InvalidLength { actual: usize, expected: usize }, | ||||
| } | ||||
| 
 | ||||
| impl<T: PrimitiveGridType> PrimitiveGrid<T> { | ||||
|     /// Creates a new [PrimitiveGrid] with the specified dimensions.
 | ||||
|     ///
 | ||||
|  | @ -155,16 +163,19 @@ impl<T: PrimitiveGridType> PrimitiveGrid<T> { | |||
|     pub fn get_col(&self, x: usize) -> Option<Vec<T>> { | ||||
|         self.data | ||||
|             .chunks_exact(self.width()) | ||||
|             .map(|row| row.get(x).map(move |x| *x)) | ||||
|             .map(|row| row.get(x).copied()) | ||||
|             .collect() | ||||
|     } | ||||
| 
 | ||||
|     /// Overwrites a column in the grid.
 | ||||
|     ///
 | ||||
|     /// Returns [None] if x is out of bounds or `col` is not of the correct size.
 | ||||
|     pub fn set_col(&mut self, x: usize, col: &[T]) -> Option<()> { | ||||
|     /// Returns [Err] if x is out of bounds or `col` is not of the correct size.
 | ||||
|     pub fn set_col(&mut self, x: usize, col: &[T]) -> Result<(), SeriesError> { | ||||
|         if col.len() != self.height() { | ||||
|             return None; | ||||
|             return Err(SeriesError::InvalidLength { | ||||
|                 expected: self.height(), | ||||
|                 actual: col.len(), | ||||
|             }); | ||||
|         } | ||||
|         let width = self.width(); | ||||
|         if self | ||||
|  | @ -176,25 +187,36 @@ impl<T: PrimitiveGridType> PrimitiveGrid<T> { | |||
|             }) | ||||
|             .all(|cell| cell.is_some()) | ||||
|         { | ||||
|             Some(()) | ||||
|             Ok(()) | ||||
|         } else { | ||||
|             None | ||||
|             Err(SeriesError::OutOfBounds {index: x, size: width}) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// Overwrites a row in the grid.
 | ||||
|     ///
 | ||||
|     /// Returns [None] if y is out of bounds or `row` is not of the correct size.
 | ||||
|     pub fn set_row(&mut self, y: usize, row: &[T]) -> Option<()> { | ||||
|     /// Returns [Err] if y is out of bounds or `row` is not of the correct size.
 | ||||
|     pub fn set_row(&mut self, y: usize, row: &[T]) -> Result<(), SeriesError> { | ||||
|         let width = self.width(); | ||||
|         self.data.chunks_exact_mut(width).nth(y).and_then(|chunk| { | ||||
|             if chunk.len() == row.len() { | ||||
|                 chunk.copy_from_slice(row); | ||||
|                 Some(()) | ||||
|             } else { | ||||
|                 None | ||||
|         if row.len() != width { | ||||
|             return Err(SeriesError::InvalidLength { | ||||
|                 expected: width, | ||||
|                 actual: row.len(), | ||||
|             }); | ||||
|         } | ||||
| 
 | ||||
|         let chunk = match self.data.chunks_exact_mut(width).nth(y) { | ||||
|             Some(row) => row, | ||||
|             None => { | ||||
|                 return Err(SeriesError::OutOfBounds { | ||||
|                     size: self.height(), | ||||
|                     index: y, | ||||
|                 }) | ||||
|             } | ||||
|         }) | ||||
|         }; | ||||
| 
 | ||||
|         chunk.copy_from_slice(row); | ||||
|         Ok(()) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | @ -283,7 +305,7 @@ impl<'t, T: PrimitiveGridType> Iterator for IterRows<'t, T> { | |||
| 
 | ||||
| #[cfg(test)] | ||||
| mod tests { | ||||
|     use crate::{DataRef, Grid, PrimitiveGrid}; | ||||
|     use crate::{DataRef, Grid, PrimitiveGrid, SeriesError}; | ||||
| 
 | ||||
|     #[test] | ||||
|     fn fill() { | ||||
|  | @ -412,9 +434,18 @@ mod tests { | |||
|         assert_eq!(grid.get_col(0), Some(vec![0, 2, 4])); | ||||
|         assert_eq!(grid.get_col(1), Some(vec![1, 3, 5])); | ||||
|         assert_eq!(grid.get_col(2), None); | ||||
|         assert_eq!(grid.set_col(0, &[5, 7, 9]), Some(())); | ||||
|         assert_eq!(grid.set_col(2, &[5, 7, 9]), None); | ||||
|         assert_eq!(grid.set_col(0, &[5, 7]), None); | ||||
|         assert_eq!(grid.set_col(0, &[5, 7, 9]), Ok(())); | ||||
|         assert_eq!( | ||||
|             grid.set_col(2, &[5, 7, 9]), | ||||
|             Err(SeriesError::OutOfBounds { size: 2, index: 2 }) | ||||
|         ); | ||||
|         assert_eq!( | ||||
|             grid.set_col(0, &[5, 7]), | ||||
|             Err(SeriesError::InvalidLength { | ||||
|                 expected: 3, | ||||
|                 actual: 2 | ||||
|             }) | ||||
|         ); | ||||
|         assert_eq!(grid.get_col(0), Some(vec![5, 7, 9])); | ||||
|     } | ||||
| 
 | ||||
|  | @ -424,9 +455,18 @@ mod tests { | |||
|         assert_eq!(grid.get_row(0), Some(vec![0, 1])); | ||||
|         assert_eq!(grid.get_row(2), Some(vec![4, 5])); | ||||
|         assert_eq!(grid.get_row(3), None); | ||||
|         assert_eq!(grid.set_row(0, &[5, 7]), Some(())); | ||||
|         assert_eq!(grid.set_row(0, &[5, 7]), Ok(())); | ||||
|         assert_eq!(grid.get_row(0), Some(vec![5, 7])); | ||||
|         assert_eq!(grid.set_row(3, &[5, 7]), None); | ||||
|         assert_eq!(grid.set_row(2, &[5, 7, 3]), None); | ||||
|         assert_eq!( | ||||
|             grid.set_row(3, &[5, 7]), | ||||
|             Err(SeriesError::OutOfBounds { size: 3, index: 3 }) | ||||
|         ); | ||||
|         assert_eq!( | ||||
|             grid.set_row(2, &[5, 7, 3]), | ||||
|             Err(SeriesError::InvalidLength { | ||||
|                 expected: 2, | ||||
|                 actual: 3 | ||||
|             }) | ||||
|         ); | ||||
|     } | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Vinzenz Schroeter
						Vinzenz Schroeter