Skip to main content

ingrid/
iterator_grid.rs

1// Copyright (c) 2020 - BytePlug
2//
3// This source file is part of Ingrid which is released under the MIT license.
4// Please refer to the LICENSE file that can be found at the root of the project
5// directory.
6//
7// Written by Jonathan De Wachter <dewachter.jonathan@gmail.com>, January 2020
8
9use std::iter::Iterator;
10use crate::coordinate::Coordinate;
11use crate::grid::Grid;
12use crate::grid_iterator::GridIterator;
13use crate::coord;
14
15/// An iterator over a grid
16///
17/// This structure is an iterator over the elements of a grid. It's constructed
18/// from the grid directly.
19///
20/// # Examples
21///
22/// ```
23/// # use ingrid::Grid;
24/// #
25/// let grid = Grid::from_rows(vec![vec![1, 2],
26///                                 vec![3, 4]]);
27///
28/// let mut iterator = grid.iterator();
29/// assert_eq!(iterator.next(), Some(&1));
30/// assert_eq!(iterator.next(), Some(&2));
31/// assert_eq!(iterator.next(), Some(&3));
32/// assert_eq!(iterator.next(), Some(&4));
33/// assert_eq!(iterator.next(), None);
34/// ```
35///
36pub struct IteratorGrid<'a, T> {
37    grid: &'a Grid<T>,
38    coordinate: Coordinate
39}
40
41impl<'a, T> IteratorGrid<'a, T> {
42    pub fn new(grid: &'a Grid<T>) -> IteratorGrid<'a, T> {
43        IteratorGrid { grid, coordinate: coord!(0, 0) }
44    }
45}
46
47impl<'a, T: Clone> Iterator for IteratorGrid<'a, T> {
48    type Item = &'a T;
49
50    fn next(&mut self) -> Option<Self::Item> {
51        if self.coordinate.y == self.grid.size().height {
52            None
53        }
54        else {
55            let value = self.grid.value(self.coordinate);
56
57            self.coordinate.x += 1;
58            if self.coordinate.x == self.grid.size().width {
59                self.coordinate.x = 0;
60                self.coordinate.y += 1;
61            }
62
63            Some(value)
64        }
65    }
66}
67
68impl<'a, T: Clone> GridIterator for IteratorGrid<'a, T> {
69    fn coordinate(&self) -> Coordinate {
70        self.coordinate
71    }
72}
73
74#[cfg(test)]
75mod tests {
76    use super::*;
77    use crate::grid::Grid;
78
79    #[test]
80    fn iterator_from_grid() {
81        let grid = Grid::from_rows(vec![vec![1, 2, 3],
82                                        vec![4, 5, 6],
83                                        vec![7, 8, 9]]);
84
85        let mut iterator = IteratorGrid::new(&grid);
86
87        assert_eq!(iterator.next(), Some(&1));
88        assert_eq!(iterator.next(), Some(&2));
89        assert_eq!(iterator.next(), Some(&3));
90        assert_eq!(iterator.next(), Some(&4));
91        assert_eq!(iterator.next(), Some(&5));
92        assert_eq!(iterator.next(), Some(&6));
93        assert_eq!(iterator.next(), Some(&7));
94        assert_eq!(iterator.next(), Some(&8));
95        assert_eq!(iterator.next(), Some(&9));
96        assert_eq!(iterator.next(), None);
97    }
98}