gridit 0.1.0

2D grid library utilizing the fun of iterators
Documentation
use crate::iter::{Positions, PositionsEnumerator};

pub struct RowIter<'a, T> {
    pub(crate) row_iter: std::slice::Iter<'a, T>,
    pub(crate) idx: usize,
}

impl<'a, T> Iterator for RowIter<'a, T> {
    type Item = &'a T;
    fn next(&mut self) -> Option<Self::Item> {
        self.row_iter.next()
    }
}

impl<'a, T: 'static> PositionsEnumerator for RowIter<'a, T> {
    fn grid_positions(self) -> Positions<Self> {
        Positions {
            next_pos: |inner, prev_pos| match prev_pos {
                None => (0, inner.idx).into(),
                Some(p) => (p.x + 1, p.y).into(),
            },
            prev_position: None,
            inner: self,
        }
    }
}

pub struct RowIterMut<'a, T> {
    pub(crate) row_iter: std::slice::IterMut<'a, T>,
    pub(crate) idx: usize,
}

impl<'a, T> Iterator for RowIterMut<'a, T> {
    type Item = &'a mut T;
    fn next(&mut self) -> Option<Self::Item> {
        self.row_iter.next()
    }
}

impl<'a, T: 'static> PositionsEnumerator for RowIterMut<'a, T> {
    fn grid_positions(self) -> Positions<Self> {
        Positions {
            next_pos: |inner, prev_pos| match prev_pos {
                None => (0, inner.idx).into(),
                Some(p) => (p.x + 1, p.y).into(),
            },
            prev_position: None,
            inner: self,
        }
    }
}

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

    #[test]
    fn row_iter_1x2() {
        let grid = Grid {
            width: 1,
            height: 2,
            items: vec![0, 1],
        };

        let mut row_iter = grid.row(0);
        assert_eq!(row_iter.next(), Some(&0));
        assert_eq!(row_iter.next(), None);

        let mut row_iter = grid.row(1);
        assert_eq!(row_iter.next(), Some(&1));
        assert_eq!(row_iter.next(), None);
    }

    #[test]
    fn row_iter_2x1() {
        let grid = Grid {
            width: 2,
            height: 1,
            items: vec![0, 1],
        };

        let mut row_iter = grid.row(0);
        assert_eq!(row_iter.next(), Some(&0));
        assert_eq!(row_iter.next(), Some(&1));
        assert_eq!(row_iter.next(), None);
    }

    #[test]
    fn row_iter_2x2() {
        let grid = Grid {
            width: 2,
            height: 2,
            items: vec![0, 0, 1, 1],
        };
        let mut row_iter = grid.row(0);
        assert_eq!(row_iter.next(), Some(&0));
        assert_eq!(row_iter.next(), Some(&0));
        assert_eq!(row_iter.next(), None);

        let mut row_iter = grid.row(1);
        assert_eq!(row_iter.next(), Some(&1));
        assert_eq!(row_iter.next(), Some(&1));
        assert_eq!(row_iter.next(), None);
    }

    #[test]
    fn row_iter_positions() {
        let grid = Grid {
            width: 4,
            height: 3,
            items: vec![0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2],
        };

        let mut row_pos = grid.row(1).grid_positions();
        assert_eq!(row_pos.next(), Some(((0, 1).into(), &1)));
        assert_eq!(row_pos.next(), Some(((1, 1).into(), &1)));
        assert_eq!(row_pos.next(), Some(((2, 1).into(), &1)));
        assert_eq!(row_pos.next(), Some(((3, 1).into(), &1)));
        assert_eq!(row_pos.next(), None);
    }

    #[test]
    fn row_iter_mut_1x2() {
        let mut grid = Grid {
            width: 1,
            height: 2,
            items: vec![0, 1],
        };

        let mut row_iter = grid.row_mut(0);
        assert_eq!(row_iter.next(), Some(&mut 0));
        assert_eq!(row_iter.next(), None);

        let mut row_iter = grid.row_mut(1);
        assert_eq!(row_iter.next(), Some(&mut 1));
        assert_eq!(row_iter.next(), None);
    }

    #[test]
    fn row_iter_mut_2x1() {
        let mut grid = Grid {
            width: 2,
            height: 1,
            items: vec![0, 1],
        };

        let mut row_iter = grid.row_mut(0);
        assert_eq!(row_iter.next(), Some(&mut 0));
        assert_eq!(row_iter.next(), Some(&mut 1));
        assert_eq!(row_iter.next(), None);
    }

    #[test]
    fn row_iter_mut_2x2() {
        let mut grid = Grid {
            width: 2,
            height: 2,
            items: vec![0, 0, 1, 1],
        };
        let mut row_iter = grid.row_mut(0);
        assert_eq!(row_iter.next(), Some(&mut 0));
        assert_eq!(row_iter.next(), Some(&mut 0));
        assert_eq!(row_iter.next(), None);

        let mut row_iter = grid.row_mut(1);
        assert_eq!(row_iter.next(), Some(&mut 1));
        assert_eq!(row_iter.next(), Some(&mut 1));
        assert_eq!(row_iter.next(), None);
    }

    #[test]
    fn row_iter_mut_positions() {
        let mut grid = Grid {
            width: 4,
            height: 3,
            items: vec![0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2],
        };

        let mut row_pos = grid.row_mut(1).grid_positions();
        assert_eq!(row_pos.next(), Some(((0, 1).into(), &mut 1)));
        assert_eq!(row_pos.next(), Some(((1, 1).into(), &mut 1)));
        assert_eq!(row_pos.next(), Some(((2, 1).into(), &mut 1)));
        assert_eq!(row_pos.next(), Some(((3, 1).into(), &mut 1)));
        assert_eq!(row_pos.next(), None);

        let mut row_pos = grid.row_mut(0).grid_positions();
        assert_eq!(row_pos.next(), Some(((0, 0).into(), &mut 0)));
        assert_eq!(row_pos.next(), Some(((1, 0).into(), &mut 0)));
        assert_eq!(row_pos.next(), Some(((2, 0).into(), &mut 0)));
        assert_eq!(row_pos.next(), Some(((3, 0).into(), &mut 0)));
        assert_eq!(row_pos.next(), None);
    }
}