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)]
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 {
41 entity: *self,
42 count_rows,
43 count_cols,
44 i: 0,
45 j: 0,
46 }
47 }
48}
49
50impl From<Position> for Entity {
51 fn from((row: usize, col: usize): Position) -> Self {
52 Self::Cell(row, col)
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 Iterator for EntityIterator {
69 type Item = Position;
70
71 fn next(&mut self) -> Option<Self::Item> {
72 if self.count_rows == 0 || self.count_cols == 0 {
73 return None;
74 }
75
76 match self.entity {
77 Entity::Cell(row, col) => {
78 self.count_cols = 0;
79 self.count_rows = 0;
80
81 Some((row, col))
82 }
83 Entity::Column(col) => {
84 if self.i >= self.count_rows {
85 return None;
86 }
87
88 let i = self.i;
89 self.i += 1;
90
91 Some((i, col))
92 }
93 Entity::Row(row) => {
94 if self.j >= self.count_cols {
95 return None;
96 }
97
98 let j = self.j;
99 self.j += 1;
100
101 Some((row, j))
102 }
103 Entity::Global => {
104 if self.j >= self.count_cols {
105 self.j = 0;
106 self.i += 1;
107
108 if self.i >= self.count_rows {
109 return None;
110 }
111 }
112
113 let j = self.j;
114 self.j += 1;
115
116 Some((self.i, j))
117 }
118 }
119 }
120}
121
122#[cfg(test)]
123mod tests {
124 use super::*;
125
126 #[test]
127 fn test_entity_iter() {
128 assert_eq!(
129 Entity::Global.iter(10, 10).collect::<Vec<_>>(),
130 vec![
131 (0, 0),
132 (0, 1),
133 (0, 2),
134 (0, 3),
135 (0, 4),
136 (0, 5),
137 (0, 6),
138 (0, 7),
139 (0, 8),
140 (0, 9),
141 (1, 0),
142 (1, 1),
143 (1, 2),
144 (1, 3),
145 (1, 4),
146 (1, 5),
147 (1, 6),
148 (1, 7),
149 (1, 8),
150 (1, 9),
151 (2, 0),
152 (2, 1),
153 (2, 2),
154 (2, 3),
155 (2, 4),
156 (2, 5),
157 (2, 6),
158 (2, 7),
159 (2, 8),
160 (2, 9),
161 (3, 0),
162 (3, 1),
163 (3, 2),
164 (3, 3),
165 (3, 4),
166 (3, 5),
167 (3, 6),
168 (3, 7),
169 (3, 8),
170 (3, 9),
171 (4, 0),
172 (4, 1),
173 (4, 2),
174 (4, 3),
175 (4, 4),
176 (4, 5),
177 (4, 6),
178 (4, 7),
179 (4, 8),
180 (4, 9),
181 (5, 0),
182 (5, 1),
183 (5, 2),
184 (5, 3),
185 (5, 4),
186 (5, 5),
187 (5, 6),
188 (5, 7),
189 (5, 8),
190 (5, 9),
191 (6, 0),
192 (6, 1),
193 (6, 2),
194 (6, 3),
195 (6, 4),
196 (6, 5),
197 (6, 6),
198 (6, 7),
199 (6, 8),
200 (6, 9),
201 (7, 0),
202 (7, 1),
203 (7, 2),
204 (7, 3),
205 (7, 4),
206 (7, 5),
207 (7, 6),
208 (7, 7),
209 (7, 8),
210 (7, 9),
211 (8, 0),
212 (8, 1),
213 (8, 2),
214 (8, 3),
215 (8, 4),
216 (8, 5),
217 (8, 6),
218 (8, 7),
219 (8, 8),
220 (8, 9),
221 (9, 0),
222 (9, 1),
223 (9, 2),
224 (9, 3),
225 (9, 4),
226 (9, 5),
227 (9, 6),
228 (9, 7),
229 (9, 8),
230 (9, 9)
231 ]
232 );
233 }
234}
235