1 | use 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)] |
26 | pub 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 | |
37 | impl 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 | |
50 | impl 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)] |
60 | pub struct EntityIterator { |
61 | entity: Entity, |
62 | count_rows: usize, |
63 | count_cols: usize, |
64 | i: usize, |
65 | j: usize, |
66 | } |
67 | |
68 | impl 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)] |
123 | mod 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 | |