use std::fmt::{Display, Formatter};
#[cfg(test)]
mod tests;
pub struct FillCanvas<T> {
rows: usize,
cols: usize,
matrix: Vec<T>, }
impl<T> FillCanvas<T> where T: Default + Clone + PartialEq {
pub fn new(rows: usize, cols: usize) -> Self {
let mut matrix = Vec::new();
matrix.resize(rows * cols, T::default());
Self { rows, cols, matrix }
}
pub fn resize(&mut self, rows: usize, cols: usize) {
self.rows = rows;
self.cols = cols;
self.matrix.resize(rows * cols, T::default());
}
pub fn clear(&mut self) {
self.matrix.fill(T::default())
}
pub fn get(&self, r: usize, c: usize) -> Option<&T> {
let index = self.index(r, c)?;
Some(&self.matrix[index])
}
pub fn get_filled(&self, r: usize, c: usize) -> Option<&T> {
self.get(r, c).and_then(|v| (v != &T::default()).then(|| v))
}
pub fn fill_cell(&mut self, v: T, r: usize, c: usize) -> Option<()> {
let index = self.index(r, c)?;
self.matrix[index] = v;
Some(())
}
pub fn fill_row(&mut self, v: T, r: usize) -> Option<()> {
let begin = self.index(r, 0)?;
let end = self.index(r, self.cols - 1)?;
for index in begin..=end {
self.matrix[index] = v.clone();
}
Some(())
}
pub fn fill_col(&mut self, v: T, c: usize) -> Option<()> {
self.index(0, c)?; for r in 0..self.rows {
let index = self.index_unchecked(r, c);
self.matrix[index] = v.clone();
}
Some(())
}
pub fn fill_area(&mut self, v: T, r0: usize, c0: usize, r1: usize, c1: usize) -> Option<()> {
if r1 < r0 || c1 < c0 { return None; } self.index(r0, c0)?; self.index(r1, c1)?; for r in r0..=r1 {
let begin = self.index_unchecked(r, c0);
let end = self.index_unchecked(r, c1);
for index in begin..=end {
self.matrix[index] = v.clone();
}
}
Some(())
}
fn index(&self, r: usize, c: usize) -> Option<usize> {
let index = self.index_unchecked(r, c);
if c < self.cols && index < self.matrix.len() { Some(index) } else { None }
}
fn index_unchecked(&self, r: usize, c: usize) -> usize {
self.cols * r + c
}
}
impl<T> Display for FillCanvas<T> where T: Clone + Default + Display + PartialEq {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.write_str("FillCanvas {\n")?;
for index in 0..self.matrix.len() {
if index % self.cols == 0 && index != 0 {
f.write_str("\n")?;
}
write!(f, "{} ", self.matrix[index])?;
}
f.write_str("\n}")
}
}