nd_matrix 0.3.0

A n-dimensional matrix type
Documentation
use std::{
    array::IntoIter,
    ops::{Index, IndexMut},
    slice::{Iter, IterMut},
};

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Point<const N: usize>([usize; N]);

impl<const D: usize> Point<D> {
    #[inline(always)]
    pub fn coordinates(&self) -> &[usize; D] {
        &self.0
    }

    #[inline(always)]
    pub fn coordinates_mut(&mut self) -> &mut [usize; D] {
        &mut self.0
    }
}

impl<const D: usize> From<[usize; D]> for Point<D> {
    fn from(point: [usize; D]) -> Self {
        Point(point)
    }
}

impl<const D: usize> IntoIterator for Point<D> {
    type Item = usize;
    type IntoIter = IntoIter<usize, D>;

    fn into_iter(self) -> Self::IntoIter {
        self.0.into_iter()
    }
}

impl<'a, const D: usize> IntoIterator for &'a Point<D> {
    type Item = &'a usize;
    type IntoIter = Iter<'a, usize>;

    fn into_iter(self) -> Self::IntoIter {
        (&self.0).into_iter()
    }
}

impl<'a, const D: usize> IntoIterator for &'a mut Point<D> {
    type Item = &'a mut usize;
    type IntoIter = IterMut<'a, usize>;

    fn into_iter(self) -> Self::IntoIter {
        (&mut self.0).into_iter()
    }
}

impl<I, const D: usize> Index<I> for Point<D>
where
    [usize]: Index<I>,
{
    type Output = <[usize] as Index<I>>::Output;

    #[inline(always)]
    fn index(&self, index: I) -> &<Self as Index<I>>::Output {
        self.0.index(index)
    }
}

impl<I, const D: usize> IndexMut<I> for Point<D>
where
    [usize]: IndexMut<I>,
{
    #[inline(always)]
    fn index_mut(&mut self, index: I) -> &mut <Self as Index<I>>::Output {
        self.0.index_mut(index)
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn coordinates() {
        let point = Point([1, 2]);

        assert_eq!(point.coordinates(), &[1, 2]);
    }

    #[test]
    fn coordinates_mut() {
        let mut point = Point([1, 2]);

        assert_eq!(point.coordinates_mut(), &mut [1, 2]);
    }

    #[test]
    fn from() {
        let point = Point::from([1, 2]);

        assert_eq!(point, Point([1, 2]));
    }

    #[test]
    fn into_iter() {
        let point = Point([1, 2]);
        let mut iter = point.into_iter();

        assert_eq!(iter.next(), Some(1));
        assert_eq!(iter.next(), Some(2));
        assert_eq!(iter.next(), None);
    }

    #[test]
    fn into_iter_ref() {
        let point = Point([1, 2]);
        let mut iter = (&point).into_iter();

        assert_eq!(iter.next(), Some(&1));
        assert_eq!(iter.next(), Some(&2));
        assert_eq!(iter.next(), None);
    }

    #[test]
    fn into_iter_mut_ref() {
        let mut point = Point([1, 2]);
        let mut iter = (&mut point).into_iter();

        assert_eq!(iter.next(), Some(&mut 1));
        assert_eq!(iter.next(), Some(&mut 2));
        assert_eq!(iter.next(), None);
    }

    #[test]
    fn index() {
        let point = Point([1, 2]);

        assert_eq!(point[0], 1);
        assert_eq!(point[1], 2);
    }

    #[test]
    fn index_mut() {
        let mut point = Point([1, 2]);

        assert_eq!(&mut point[0], &mut 1);
        assert_eq!(&mut point[1], &mut 2);
    }
}