1use core::marker::PhantomData;
4
5use crate::grid::config::Entity;
6use crate::settings::object::Object;
7
8pub trait ObjectIterator<R>: Object<R> {
11 fn skip(self, n: usize) -> SkipObject<Self, R>
13 where
14 Self: Sized,
15 {
16 SkipObject::new(self, n)
17 }
18
19 fn step_by(self, n: usize) -> StepByObject<Self, R>
21 where
22 Self: Sized,
23 {
24 StepByObject::new(self, n)
25 }
26
27 fn filter<F>(self, predicate: F) -> FilterObject<Self, F, R>
29 where
30 Self: Sized,
31 F: Fn(Entity) -> bool,
32 {
33 FilterObject::new(self, predicate)
34 }
35}
36
37impl<T, R> ObjectIterator<R> for T where T: Object<R> {}
38
39#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default, Hash)]
41pub struct SkipObject<O, R> {
42 obj: O,
43 n: usize,
44 _records: PhantomData<R>,
45}
46
47impl<O, R> SkipObject<O, R> {
48 fn new(obj: O, n: usize) -> Self {
49 Self {
50 obj,
51 n,
52 _records: PhantomData,
53 }
54 }
55}
56
57impl<O, R> Object<R> for SkipObject<O, R>
58where
59 O: Object<R>,
60{
61 type Iter = SkipObjectIter<O::Iter>;
62
63 fn cells(&self, records: &R) -> Self::Iter {
64 SkipObjectIter::new(self.obj.cells(records), self.n)
65 }
66}
67
68#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default, Hash)]
70pub struct SkipObjectIter<I> {
71 iter: I,
72 n: usize,
73}
74
75impl<I> SkipObjectIter<I> {
76 fn new(iter: I, n: usize) -> Self {
77 Self { iter, n }
78 }
79}
80
81impl<I> Iterator for SkipObjectIter<I>
82where
83 I: Iterator,
84{
85 type Item = I::Item;
86
87 fn next(&mut self) -> Option<Self::Item> {
88 while self.n > 0 {
89 self.n -= 1;
90 let _ = self.iter.next()?;
91 }
92
93 self.iter.next()
94 }
95}
96
97#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default, Hash)]
99pub struct StepByObject<O, R> {
100 obj: O,
101 n: usize,
102 _records: PhantomData<R>,
103}
104
105impl<O, R> StepByObject<O, R> {
106 fn new(obj: O, n: usize) -> Self {
107 Self {
108 obj,
109 n,
110 _records: PhantomData,
111 }
112 }
113}
114
115impl<O, R> Object<R> for StepByObject<O, R>
116where
117 O: Object<R>,
118{
119 type Iter = StepByObjectIter<O::Iter>;
120
121 fn cells(&self, records: &R) -> Self::Iter {
122 StepByObjectIter::new(self.obj.cells(records), self.n)
123 }
124}
125
126#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default, Hash)]
128pub struct StepByObjectIter<I> {
129 iter: I,
130 step: usize,
131 end: bool,
132}
133
134impl<I> StepByObjectIter<I> {
135 fn new(iter: I, step: usize) -> Self {
136 let end = step == 0;
137
138 Self { iter, step, end }
139 }
140}
141
142impl<I> Iterator for StepByObjectIter<I>
143where
144 I: Iterator,
145{
146 type Item = I::Item;
147
148 fn next(&mut self) -> Option<Self::Item> {
149 if self.end {
150 return None;
151 }
152
153 let item = self.iter.next();
154 let _ = item.as_ref()?;
155
156 for _ in 0..self.step - 1 {
157 let next = self.iter.next();
158 if next.is_none() {
159 self.end = true;
160 break;
161 }
162 }
163
164 item
165 }
166}
167
168#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default, Hash)]
170pub struct FilterObject<O, F, R> {
171 obj: O,
172 f: F,
173 _records: PhantomData<R>,
174}
175
176impl<O, F, R> FilterObject<O, F, R> {
177 fn new(obj: O, f: F) -> Self {
178 Self {
179 obj,
180 f,
181 _records: PhantomData,
182 }
183 }
184}
185
186impl<O, R, F> Object<R> for FilterObject<O, F, R>
187where
188 O: Object<R>,
189 F: Fn(Entity) -> bool + Clone,
190{
191 type Iter = FilterObjectIter<O::Iter, F>;
192
193 fn cells(&self, records: &R) -> Self::Iter {
194 FilterObjectIter::new(self.obj.cells(records), self.f.clone())
195 }
196}
197
198#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default, Hash)]
200pub struct FilterObjectIter<I, F> {
201 iter: I,
202 f: F,
203}
204
205impl<I, F> FilterObjectIter<I, F> {
206 fn new(iter: I, f: F) -> Self {
207 Self { iter, f }
208 }
209}
210
211impl<I, F> Iterator for FilterObjectIter<I, F>
212where
213 I: Iterator<Item = Entity>,
214 F: Fn(Entity) -> bool,
215{
216 type Item = I::Item;
217
218 fn next(&mut self) -> Option<Self::Item> {
219 loop {
220 match self.iter.next() {
221 Some(item) => {
222 if (self.f)(item) {
223 return Some(item);
224 }
225 }
226 None => return None,
227 }
228 }
229 }
230}
231
232#[cfg(test)]
233mod tests {
234 use crate::{
235 grid::records::vec_records::VecRecords,
236 settings::object::{Columns, Rows},
237 };
238
239 use super::*;
240
241 #[test]
242 fn test_skip_iterator() {
243 use Entity::*;
244
245 assert_eq!(
246 cells(Rows::new(1..5).skip(1), 10, 10),
247 [Row(2), Row(3), Row(4)]
248 );
249
250 assert_eq!(
251 cells(Columns::new(5..).skip(1), 10, 10),
252 [Column(6), Column(7), Column(8), Column(9)]
253 );
254
255 assert_eq!(cells((1, 5).skip(1), 10, 10), []);
256 assert_eq!(cells((1, 5).skip(0), 10, 10), [Cell(1, 5)]);
257
258 assert_eq!(
259 cells(Rows::new(1..5).skip(0), 10, 10),
260 [Row(1), Row(2), Row(3), Row(4)]
261 );
262 }
263
264 #[test]
265 fn test_step_by_iterator() {
266 use Entity::*;
267
268 assert_eq!(cells(Rows::new(1..5).step_by(0), 10, 10), []);
269 assert_eq!(
270 cells(Rows::new(1..5).step_by(1), 10, 10),
271 [Row(1), Row(2), Row(3), Row(4)]
272 );
273 assert_eq!(cells(Rows::new(1..5).step_by(2), 10, 10), [Row(1), Row(3)]);
274
275 assert_eq!(
276 cells(Columns::new(5..).step_by(1), 10, 10),
277 [Column(5), Column(6), Column(7), Column(8), Column(9)]
278 );
279
280 assert_eq!(cells((1, 5).step_by(2), 10, 10), [Cell(1, 5)]);
281 assert_eq!(cells((1, 5).step_by(1), 10, 10), [Cell(1, 5)]);
282
283 assert_eq!(cells(Rows::new(1..5).step_by(100), 10, 10), [Row(1)]);
284 }
285
286 #[test]
287 fn test_filter_iterator() {
288 use Entity::*;
289
290 assert_eq!(
291 cells(Rows::new(1..5).filter(|i| matches!(i, Row(3))), 10, 10),
292 [Row(3)]
293 );
294 assert_eq!(cells(Rows::new(1..5).filter(|_| false), 10, 10), []);
295 assert_eq!(
296 cells(Rows::new(1..5).filter(|_| true), 10, 10),
297 [Row(1), Row(2), Row(3), Row(4)]
298 );
299 }
300
301 fn cells<O>(o: O, count_rows: usize, count_cols: usize) -> Vec<Entity>
302 where
303 O: Object<VecRecords<String>>,
304 {
305 let data = vec![vec![String::default(); count_cols]; count_rows];
306 let records = VecRecords::new(data);
307 o.cells(&records).collect::<Vec<_>>()
308 }
309}