valib 0.2.6

valflrt's utility crate
Documentation
use std::ops::{Index, IndexMut};

/// A struct that represents a 2D array.
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct Array2<T> {
    pub width: usize,
    pub height: usize,
    pub vec: Vec<T>,
}

impl<T> Array2<T> {
    /// Creates a 2D array filled with the given value.
    pub fn filled_with(value: T, width: usize, height: usize) -> Self
    where
        T: Clone,
    {
        Self {
            width,
            height,
            vec: vec![value; height * width],
        }
    }

    /// Returns a reference to an element.
    pub fn get(&self, index: (usize, usize)) -> Option<&T> {
        let index = self.map_index(index);
        self.vec.get(index)
    }

    /// Returns a mutable reference to an element.
    pub fn get_mut(&mut self, index: (usize, usize)) -> Option<&mut T> {
        let index = self.map_index(index);
        self.vec.get_mut(index)
    }

    #[inline]
    fn map_index(&self, index: (usize, usize)) -> usize {
        index.0 + index.1 * self.width
    }
}

impl<T> Index<(usize, usize)> for Array2<T> {
    type Output = T;

    fn index(&self, index: (usize, usize)) -> &Self::Output {
        self.get(index)
            .unwrap_or_else(|| panic!("index {:?} out of bounds", index))
    }
}
impl<T> IndexMut<(usize, usize)> for Array2<T> {
    fn index_mut(&mut self, index: (usize, usize)) -> &mut Self::Output {
        self.get_mut(index)
            .unwrap_or_else(|| panic!("index {:?} out of bounds", index))
    }
}

/// A struct that represents a 3D array.
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct Array3<T> {
    pub width: usize,
    pub height: usize,
    pub depth: usize,
    pub vec: Vec<T>,
}

impl<T> Array3<T> {
    /// Creates a 2D array filled with the given value.
    pub fn filled_with(value: T, width: usize, height: usize, depth: usize) -> Self
    where
        T: Clone,
    {
        Self {
            width,
            height,
            depth,
            vec: vec![value; height * width * depth],
        }
    }

    /// Returns a reference to an element.
    pub fn get(&self, index: (usize, usize, usize)) -> Option<&T> {
        let index = self.map_index(index);
        self.vec.get(index)
    }

    /// Returns a mutable reference to an element.
    pub fn get_mut(&mut self, index: (usize, usize, usize)) -> Option<&mut T> {
        let index = self.map_index(index);
        self.vec.get_mut(index)
    }

    #[inline]
    fn map_index(&self, index: (usize, usize, usize)) -> usize {
        index.0 + index.1 * self.width + index.2 * self.width * self.height
    }
}

impl<T> Index<(usize, usize, usize)> for Array3<T> {
    type Output = T;

    fn index(&self, index: (usize, usize, usize)) -> &Self::Output {
        self.get(index)
            .unwrap_or_else(|| panic!("index {:?} out of bounds", index))
    }
}
impl<T> IndexMut<(usize, usize, usize)> for Array3<T> {
    fn index_mut(&mut self, index: (usize, usize, usize)) -> &mut Self::Output {
        self.get_mut(index)
            .unwrap_or_else(|| panic!("index {:?} out of bounds", index))
    }
}