#[derive(Debug)]
pub struct Matrix<T: Clone> {
matrix: Vec<Vec<Option<T>>>,
}
impl<T: Clone> Matrix<T> {
pub fn new(size: (usize, usize)) -> Matrix<T> {
let (m, n) = size;
let mut matrix: Vec<Vec<Option<T>>> = Vec::new();
let row = vec![None; n];
for _ in 0..m {
matrix.push(row.clone());
}
return Matrix::<T> { matrix };
}
pub fn get(&mut self, pos: (usize, usize)) -> Option<T> {
let (m, n) = pos;
let item = self.matrix[m][n].clone();
if item.is_some() {
self.delete(pos).unwrap();
}
return item;
}
pub fn get_ref(&self, pos: (usize, usize)) -> Option<&T> {
let (m, n) = pos;
return self.matrix[m][n].as_ref();
}
pub fn get_mut(&mut self, pos: (usize, usize)) -> Option<&mut T> {
let (m, n) = pos;
return self.matrix[m][n].as_mut();
}
pub fn set(&mut self, item: T, pos: (usize, usize)) -> Result<(), ()> {
if !self.is_in_bounds((pos.0 as isize, pos.1 as isize)) {
return Err(());
}
let (m, n) = pos;
self.matrix[m][n] = Some(item);
return Ok(());
}
pub fn delete(&mut self, pos: (usize, usize)) -> Result<(), ()> {
if !self.is_in_bounds((pos.0 as isize, pos.1 as isize)){
return Err(());
}
let (m, n) = pos;
self.matrix[m][n] = None;
return Ok(());
}
pub fn clear(&mut self){
let size = (self.matrix.len(), self.matrix[0].len());
let new_matrix = Matrix::<T>::new(size);
self.matrix = new_matrix.matrix;
}
pub fn translate(&mut self, from: (usize, usize), dir: (isize, isize)) -> Result<(), ()> {
let to = (from.0 as isize + dir.0, from.1 as isize + dir.1);
if !self.is_in_bounds(to) {
return Err(());
}
let to = (to.0 as usize, to.1 as usize);
let item = self.get_ref(from);
if item.is_none(){
return Err(());
}
let item = item.unwrap().clone();
self.delete(from)?;
self.set(item, to)?;
return Ok(());
}
fn is_in_bounds(&self, pos: (isize, isize)) -> bool {
if pos.0 < 0 || pos.0 > (self.matrix.len() - 1) as isize {
return false;
}
if pos.1 < 0 || pos.1 > (self.matrix[0].len() - 1) as isize {
return false;
}
return true;
}
}
impl<T: Clone + Copy> From<Vec<Vec<T>>> for Matrix<T> {
fn from(items: Vec<Vec<T>>) -> Self {
let m = items.len();
let n = items.first().unwrap().len();
let mut matrix = Matrix::new((m, n));
for i in 0..m {
for j in 0..n {
matrix.set(items[i][j], (i, j)).unwrap();
}
}
return matrix;
}
}