papergrid/config/
entity.rs

1use super::Position;
2
3/// Entity a structure which represent a set of cells.
4///
5/// For example such table:
6///
7/// ```text
8/// ┌───┬───┐
9/// │ 0 │ 1 │
10/// ├───┼───┤
11/// │ 1 │ 2 │
12/// └───┴───┘
13/// ```
14///
15/// - has 4 cells.
16///   Which indexes are (0, 0), (0, 1), (1, 0), (1, 1).
17///
18/// - has 2 rows.
19///   Which indexes are 0, 1.
20///
21/// - has 2 column.
22///   Which indexes are 0, 1.
23///
24/// In [`Entity`] terms, all cells on the grid we call `Global`.
25#[derive(PartialEq, Eq, Debug, Hash, Clone, Copy, PartialOrd, Ord)]
26pub enum Entity {
27    /// All cells on the grid.
28    Global,
29    /// All cells in a column on the grid.
30    Column(usize),
31    /// All cells in a row on the grid.
32    Row(usize),
33    /// A particular cell (row, column) on the grid.
34    Cell(usize, usize),
35}
36
37impl Entity {
38    /// Iterate over cells which are covered via the [`Entity`].
39    pub fn iter(&self, count_rows: usize, count_cols: usize) -> EntityIterator {
40        EntityIterator::new(*self, count_rows, count_cols)
41    }
42}
43
44impl From<Position> for Entity {
45    fn from(pos: Position) -> Self {
46        Self::Cell(pos.row, pos.col)
47    }
48}
49
50impl From<(usize, usize)> for Entity {
51    fn from(pos: (usize, usize)) -> Self {
52        Self::Cell(pos.0, pos.1)
53    }
54}
55
56/// An iterator over cells.
57///
58/// Produced from [`Entity::iter`].
59#[derive(Debug, Clone)]
60pub struct EntityIterator {
61    entity: Entity,
62    count_rows: usize,
63    count_cols: usize,
64    i: usize,
65    j: usize,
66}
67
68impl EntityIterator {
69    fn new(entity: Entity, count_rows: usize, count_cols: usize) -> Self {
70        Self {
71            entity,
72            count_rows,
73            count_cols,
74            i: 0,
75            j: 0,
76        }
77    }
78}
79
80impl Iterator for EntityIterator {
81    type Item = Position;
82
83    fn next(&mut self) -> Option<Self::Item> {
84        if self.count_rows == 0 || self.count_cols == 0 {
85            return None;
86        }
87
88        match self.entity {
89            Entity::Cell(row, col) => {
90                self.count_cols = 0;
91                self.count_rows = 0;
92
93                Some(Position::new(row, col))
94            }
95            Entity::Column(col) => {
96                if self.i >= self.count_rows {
97                    return None;
98                }
99
100                let i = self.i;
101                self.i += 1;
102
103                Some(Position::new(i, col))
104            }
105            Entity::Row(row) => {
106                if self.j >= self.count_cols {
107                    return None;
108                }
109
110                let j = self.j;
111                self.j += 1;
112
113                Some(Position::new(row, j))
114            }
115            Entity::Global => {
116                if self.j >= self.count_cols {
117                    self.j = 0;
118                    self.i += 1;
119
120                    if self.i >= self.count_rows {
121                        return None;
122                    }
123                }
124
125                let j = self.j;
126                self.j += 1;
127
128                Some(Position::new(self.i, j))
129            }
130        }
131    }
132}
133
134#[cfg(test)]
135mod tests {
136    use super::*;
137
138    #[test]
139    fn test_entity_iter() {
140        assert_eq!(
141            Entity::Global.iter(10, 10).collect::<Vec<_>>(),
142            vec![
143                Position::new(0, 0),
144                Position::new(0, 1),
145                Position::new(0, 2),
146                Position::new(0, 3),
147                Position::new(0, 4),
148                Position::new(0, 5),
149                Position::new(0, 6),
150                Position::new(0, 7),
151                Position::new(0, 8),
152                Position::new(0, 9),
153                Position::new(1, 0),
154                Position::new(1, 1),
155                Position::new(1, 2),
156                Position::new(1, 3),
157                Position::new(1, 4),
158                Position::new(1, 5),
159                Position::new(1, 6),
160                Position::new(1, 7),
161                Position::new(1, 8),
162                Position::new(1, 9),
163                Position::new(2, 0),
164                Position::new(2, 1),
165                Position::new(2, 2),
166                Position::new(2, 3),
167                Position::new(2, 4),
168                Position::new(2, 5),
169                Position::new(2, 6),
170                Position::new(2, 7),
171                Position::new(2, 8),
172                Position::new(2, 9),
173                Position::new(3, 0),
174                Position::new(3, 1),
175                Position::new(3, 2),
176                Position::new(3, 3),
177                Position::new(3, 4),
178                Position::new(3, 5),
179                Position::new(3, 6),
180                Position::new(3, 7),
181                Position::new(3, 8),
182                Position::new(3, 9),
183                Position::new(4, 0),
184                Position::new(4, 1),
185                Position::new(4, 2),
186                Position::new(4, 3),
187                Position::new(4, 4),
188                Position::new(4, 5),
189                Position::new(4, 6),
190                Position::new(4, 7),
191                Position::new(4, 8),
192                Position::new(4, 9),
193                Position::new(5, 0),
194                Position::new(5, 1),
195                Position::new(5, 2),
196                Position::new(5, 3),
197                Position::new(5, 4),
198                Position::new(5, 5),
199                Position::new(5, 6),
200                Position::new(5, 7),
201                Position::new(5, 8),
202                Position::new(5, 9),
203                Position::new(6, 0),
204                Position::new(6, 1),
205                Position::new(6, 2),
206                Position::new(6, 3),
207                Position::new(6, 4),
208                Position::new(6, 5),
209                Position::new(6, 6),
210                Position::new(6, 7),
211                Position::new(6, 8),
212                Position::new(6, 9),
213                Position::new(7, 0),
214                Position::new(7, 1),
215                Position::new(7, 2),
216                Position::new(7, 3),
217                Position::new(7, 4),
218                Position::new(7, 5),
219                Position::new(7, 6),
220                Position::new(7, 7),
221                Position::new(7, 8),
222                Position::new(7, 9),
223                Position::new(8, 0),
224                Position::new(8, 1),
225                Position::new(8, 2),
226                Position::new(8, 3),
227                Position::new(8, 4),
228                Position::new(8, 5),
229                Position::new(8, 6),
230                Position::new(8, 7),
231                Position::new(8, 8),
232                Position::new(8, 9),
233                Position::new(9, 0),
234                Position::new(9, 1),
235                Position::new(9, 2),
236                Position::new(9, 3),
237                Position::new(9, 4),
238                Position::new(9, 5),
239                Position::new(9, 6),
240                Position::new(9, 7),
241                Position::new(9, 8),
242                Position::new(9, 9)
243            ]
244        );
245    }
246}