1use crate::{Coordinate, Matrix};
4use crate::column::Column;
5use crate::matrix_address::MatrixAddress;
6use crate::row::Row;
7
8pub struct MatrixForwardIterator<I>
11 where I: Coordinate
12{
13 end_exclusive: MatrixAddress<I>,
14 cursor: Option<MatrixAddress<I>>
15}
16
17impl <I> MatrixForwardIterator<I>
18 where I: Coordinate {
19 pub(crate) fn new(end_exclusive: MatrixAddress<I>) -> Self {
20 if end_exclusive == MatrixAddress::default() {
21 MatrixForwardIterator{
22 end_exclusive,
23 cursor: None,
24 }
25 } else {
26 MatrixForwardIterator{
27 end_exclusive,
28 cursor: Some(MatrixAddress::default()),
29 }
30 }
31 }
32}
33
34impl <I> Iterator for MatrixForwardIterator<I>
35 where I: Coordinate {
36 type Item = MatrixAddress<I>;
37
38 fn next(&mut self) -> Option<Self::Item> {
39 let result = self.cursor;
40 let next = self.cursor;
41 match next {
42 None => {},
43 Some(mut v) => {
44 v.column = v.column + I::unit();
45 if v.column == self.end_exclusive.column {
46 v.row = v.row + I::unit();
47 if v.row == self.end_exclusive.row {
48 self.cursor = None;
49 } else {
50 v.column = I::default();
51 self.cursor = Some(v)
52 }
53 } else {
54 self.cursor = Some(v);
55 }
56 }
57 }
58 result
59 }
60}
61
62pub struct MatrixValueIterator<'a, T, I>
65where
66 T: 'a,
67 I: Coordinate,
68{
69 matrix: &'a dyn Matrix<'a, T, I>,
70 addrs: MatrixForwardIterator<I>,
71}
72
73impl <'a, T, I> MatrixValueIterator<'a, T, I>
74where
75 T: 'static,
76 I: Coordinate,
77{
78 pub(crate) fn new(matrix: &'a dyn Matrix<'a, T, I>) -> Self {
79 MatrixValueIterator{
80 matrix,
81 addrs: matrix.addresses(),
82 }
83 }
84}
85
86impl <'a, T, I> Iterator for MatrixValueIterator<'a, T, I>
87where
88 T: 'a,
89 I: Coordinate {
90 type Item = &'a T;
91
92 fn next(&mut self) -> Option<Self::Item> {
93 match self.addrs.next() {
94 None => None,
95 Some(addr) => Some(self.matrix.get(addr).unwrap()),
96 }
97 }
98}
99
100pub struct MatrixForwardIndexedIterator<'a, T, I>
103where
104 T: 'a,
105 I: Coordinate,
106{
107 matrix: &'a dyn Matrix<'a, T, I>,
108 addrs: MatrixForwardIterator<I>,
109}
110
111impl <'a, T, I> MatrixForwardIndexedIterator<'a, T, I>
112where
113 T: 'static,
114 I: Coordinate,
115{
116 pub(crate) fn new(matrix: &'a dyn Matrix<'a, T, I>) -> Self {
117 MatrixForwardIndexedIterator{
118 matrix,
119 addrs: MatrixForwardIterator::new(MatrixAddress{
120 row: matrix.row_count(),
121 column: matrix.column_count(),
122 }),
123 }
124 }
125}
126
127impl <'a, T, I> Iterator for MatrixForwardIndexedIterator<'a, T, I>
128where
129 T: 'static,
130 I: Coordinate,
131{
132 type Item = (MatrixAddress<I>, &'a T);
133
134 fn next(&mut self) -> Option<Self::Item> {
135 match self.addrs.next() {
136 None => None,
137 Some(a) => Some((a, &self.matrix[a]))
138 }
139 }
140}
141
142pub struct MatrixRowIterator<'a, T, I>
143where
144 T: 'static,
145 I: Coordinate {
146 matrix: &'a dyn Matrix<'a, T, I>,
147 row: I,
148 column_cursor_forward: I,
149 column_cursor_back: I,
150 terminated: bool,
151}
152
153impl <'a, T, I> MatrixRowIterator<'a, T, I>
154where
155 T: 'a,
156 I: Coordinate
157{
158 pub(crate) fn new(matrix: &'a dyn Matrix<'a, T, I>, row: I) -> Self {
159 MatrixRowIterator{
160 matrix,
161 row,
162 column_cursor_forward: I::unit() - I::unit(),
163 column_cursor_back: matrix.column_count() - I::unit(),
164 terminated: matrix.column_count() == I::unit() - I::unit(),
165 }
166 }
167}
168
169impl <'a, T, I> Iterator for MatrixRowIterator<'a, T, I>
170where
171 T: 'a,
172 I: Coordinate,
173{
174 type Item = &'a T;
175
176 fn next(&mut self) -> Option<Self::Item> {
177 if self.terminated {
181 None
182 } else {
183 let addr = MatrixAddress{
184 row: self.row,
185 column: self.column_cursor_forward,
186 };
187 let result = Some(&self.matrix[addr]);
188 if self.column_cursor_forward == self.column_cursor_back {
189 self.terminated = true;
190 }
191 self.column_cursor_forward = self.column_cursor_forward + I::unit();
192 result
193 }
194 }
195}
196
197impl <'a, T, I> DoubleEndedIterator for MatrixRowIterator<'a, T, I>
198where
199 T: 'a,
200 I: Coordinate,
201{
202 fn next_back(&mut self) -> Option<Self::Item> {
203 if self.terminated {
204 None
205 } else {
206 let addr = MatrixAddress{
207 row: self.row,
208 column: self.column_cursor_back,
209 };
210 let result = Some(&self.matrix[addr]);
211 if self.column_cursor_back == self.column_cursor_forward {
212 self.terminated = true;
213 } else {
214 self.column_cursor_back = self.column_cursor_back - I::unit();
215 }
216 result
217 }
218 }
219}
220
221pub struct MatrixRowsIterator<'a, T, I>
222where
223 T: 'static,
224 I: Coordinate {
225 matrix: &'a dyn Matrix<'a, T, I>,
226 row_cursor_forward: I,
227 row_cursor_back: I,
228 terminated: bool,
229}
230
231impl <'a, T, I> MatrixRowsIterator<'a, T, I>
232where
233 T: 'a,
234 I: Coordinate
235{
236 pub(crate) fn new(matrix: &'a dyn Matrix<'a, T, I>) -> Self {
237 MatrixRowsIterator{
238 matrix,
239 row_cursor_forward: I::unit() - I::unit(),
240 row_cursor_back: matrix.row_count() - I::unit(),
241 terminated: matrix.row_count() == I::unit() - I::unit(),
242 }
243 }
244}
245
246impl <'a, T, I> Iterator for MatrixRowsIterator<'a, T, I>
247where
248 T: 'a,
249 I: Coordinate,
250{
251 type Item = Row<'a, T, I>;
252
253 fn next(&mut self) -> Option<Self::Item> {
254 if self.terminated {
258 None
259 } else {
260 let row : Row<T, I> = Row::new(self.matrix, self.row_cursor_forward);
261 if self.row_cursor_forward == self.row_cursor_back {
262 self.terminated = true;
263 }
264 self.row_cursor_forward = self.row_cursor_forward + I::unit();
265 Some(row)
266 }
267 }
268}
269
270impl <'a, T, I> DoubleEndedIterator for MatrixRowsIterator<'a, T, I>
271where
272 T: 'a,
273 I: Coordinate,
274{
275 fn next_back(&mut self) -> Option<Self::Item> {
276 if self.terminated {
277 None
278 } else {
279 let row : Row<T, I> = Row::new(self.matrix, self.row_cursor_back);
280 if self.row_cursor_forward == self.row_cursor_back {
281 self.terminated = true;
282 } else {
283 self.row_cursor_back = self.row_cursor_back - I::unit();
284 }
285 Some(row)
286 }
287 }
288}
289
290
291pub struct MatrixColumnIterator<'a, T, I>
292where
293 T: 'static,
294 I: Coordinate {
295 matrix: &'a dyn Matrix<'a, T, I>,
296 column: I,
297 row_cursor_forward: I,
298 row_cursor_back: I,
299 terminated: bool,
300}
301
302impl <'a, T, I> MatrixColumnIterator<'a, T, I>
303where
304 T: 'a,
305 I: Coordinate
306{
307 pub(crate) fn new(matrix: &'a dyn Matrix<'a, T, I>, column: I) -> Self {
308 MatrixColumnIterator{
309 matrix,
310 column,
311 row_cursor_forward: I::unit() - I::unit(),
312 row_cursor_back: matrix.row_count() - I::unit(),
313 terminated: matrix.row_count() == I::unit() - I::unit(),
314 }
315 }
316}
317
318impl <'a, T, I> Iterator for MatrixColumnIterator<'a, T, I>
319where
320 T: 'a,
321 I: Coordinate,
322{
323 type Item = &'a T;
324
325 fn next(&mut self) -> Option<Self::Item> {
326 if self.terminated {
330 None
331 } else {
332 let addr = MatrixAddress{
333 row: self.row_cursor_forward,
334 column: self.column,
335 };
336 let result = Some(&self.matrix[addr]);
337 if self.row_cursor_forward == self.row_cursor_back {
338 self.terminated = true;
339 }
340 self.row_cursor_forward = self.row_cursor_forward + I::unit();
341 result
342 }
343 }
344}
345
346impl <'a, T, I> DoubleEndedIterator for MatrixColumnIterator<'a, T, I>
347where
348 T: 'a,
349 I: Coordinate,
350{
351 fn next_back(&mut self) -> Option<Self::Item> {
352 if self.terminated {
353 None
354 } else {
355 let addr = MatrixAddress{
356 row: self.row_cursor_back,
357 column: self.column,
358 };
359 let result = Some(&self.matrix[addr]);
360 if self.row_cursor_back == self.row_cursor_forward {
361 self.terminated = true;
362 } else {
363 self.row_cursor_back = self.row_cursor_back - I::unit();
364 }
365 result
366 }
367 }
368}
369
370pub struct MatrixColumnsIterator<'a, T, I>
371where
372 T: 'a,
373 I: Coordinate,
374{
375 matrix: &'a dyn Matrix<'a, T, I>,
376 column_cursor_forward: I,
377 column_cursor_back: I,
378 terminated: bool,
379}
380
381impl <'a, T, I> MatrixColumnsIterator<'a, T, I>
382where
383 T: 'static,
384 I: Coordinate
385{
386 pub(crate) fn new(matrix: &'a dyn Matrix<'a, T, I>) -> Self {
387 MatrixColumnsIterator{
388 matrix,
389 column_cursor_forward: I::unit() - I::unit(),
390 column_cursor_back: matrix.column_count() - I::unit(),
391 terminated: matrix.row_count() == I::unit() - I::unit(),
392 }
393 }
394}
395
396impl <'a, T, I> Iterator for MatrixColumnsIterator<'a, T, I>
397where
398 T: 'a,
399 I: Coordinate,
400{
401 type Item = Column<'a, T, I>;
402
403 fn next(&mut self) -> Option<Self::Item> {
404 if self.terminated {
408 None
409 } else {
410 let column : Column<T, I> = Column::new(self.matrix, self.column_cursor_forward);
411 if self.column_cursor_forward == self.column_cursor_back {
412 self.terminated = true;
413 }
414 self.column_cursor_forward = self.column_cursor_forward + I::unit();
415 Some(column)
416 }
417 }
418}
419
420impl <'a, T, I> DoubleEndedIterator for MatrixColumnsIterator<'a, T, I>
421where
422 T: 'a,
423 I: Coordinate,
424{
425 fn next_back(&mut self) -> Option<Self::Item> {
426 if self.terminated {
427 None
428 } else {
429 let column : Column<T, I> = Column::new(self.matrix, self.column_cursor_back);
430 if self.column_cursor_forward == self.column_cursor_back {
431 self.terminated = true;
432 } else {
433 self.column_cursor_back = self.column_cursor_back - I::unit();
434 }
435 Some(column)
436 }
437 }
438}
439
440#[cfg(test)]
441mod tests {
442 use crate::factories::new_default_matrix;
443 use crate::format::FormatOptions;
444 use super::*;
445
446 fn u8addr(row: u8, column: u8) -> MatrixAddress<u8> {
447 MatrixAddress{row, column}
448 }
449
450 #[test]
451 fn iterator_as_expected() {
452 let end_exclusive = u8addr(3, 2);
453 let iter = MatrixForwardIterator::new(end_exclusive);
454 let values: Vec<MatrixAddress<u8>> = iter.collect();
455 assert_eq!(values, vec![
456 u8addr(0, 0), u8addr(0, 1),
457 u8addr(1, 0), u8addr(1, 1),
458 u8addr(2, 0), u8addr(2, 1),
459 ]);
460 }
461
462 #[test]
463 fn empty_matrix_iterator_is_empty() {
464 let end_exclusive = u8addr(0, 0);
465 let iter = MatrixForwardIterator::new(end_exclusive);
466 let values: Vec<MatrixAddress<u8>> = iter.collect();
467 assert!(values.is_empty());
468 }
469
470 #[test]
471 fn indexed_iterator_as_expected() {
472 let opts = FormatOptions{
473 row_delimiter: "|".to_string(),
474 column_delimiter: ",".to_string(),
475 };
476 let matrix = opts.parse_matrix(
477 "a,bc,d|d,ef,g",
478 |x| x.to_string()).unwrap();
479 let mut iter = matrix.indexed_iter();
480 let (a1, v1) = (&mut iter).next().unwrap();
481 assert_eq!(a1, u8addr(0, 0));
482 assert_eq!(v1, "a");
483 let (a2, v2) = (&mut iter).next().unwrap();
484 assert_eq!(a2, u8addr(0, 1));
485 assert_eq!(v2, "bc");
486 let (a3, v3) = (&mut iter).next().unwrap();
487 assert_eq!(a3, u8addr(0, 2));
488 assert_eq!(v3, "d");
489 let (a4, v4) = (&mut iter).next().unwrap();
490 assert_eq!(a4, u8addr(1, 0));
491 assert_eq!(v4, "d");
492 let (a5, v5) = (&mut iter).next().unwrap();
493 assert_eq!(a5, u8addr(1, 1));
494 assert_eq!(v5, "ef");
495 let (a6, v6) = (&mut iter).next().unwrap();
496 assert_eq!(a6, u8addr(1, 2));
497 assert_eq!(v6, "g");
498 assert!(iter.next().is_none());
499 }
500
501 #[test]
502 fn empty_indexed_iterator_as_expected() {
503 let matrix = new_default_matrix::<u8, u8>(0, 0).unwrap();
504 let mut iter = matrix.indexed_iter();
505 assert!((&mut iter).next().is_none());
506 }
507
508 fn ascii_parse_opts<'a>() -> FormatOptions {
509 FormatOptions{
510 row_delimiter: "\n".to_string(),
511 column_delimiter: "".to_string(),
512 }
513 }
514
515 #[test]
516 fn row_iterator_forward_only() {
517 let opts = ascii_parse_opts();
518 let matrix = opts.parse_matrix::<String, u8>("ABC\nDEF", |x| x.to_string()).unwrap();
519 let row0 = matrix.row(0).unwrap().iter();
520 let values: Vec<&String> = row0.collect();
521 assert_eq!(values, vec!["A", "B", "C"]);
522 }
523
524 #[test]
525 fn row_iterator_reverse_only() {
526 let opts = ascii_parse_opts();
527 let matrix = opts.parse_matrix::<String, u8>("ABC\nDEF", |x| x.to_string()).unwrap();
528 let row0 = matrix.row(0).unwrap().iter().rev();
529 let values: Vec<&String> = row0.collect();
530 assert_eq!(values, vec!["C", "B", "A"]);
531 }
532
533 #[test]
534 fn row_iterator_forward_passes_reverse() {
535 let opts = ascii_parse_opts();
536 let matrix = opts.parse_matrix::<String, u8>("ABC\nDEF", |x| x.to_string()).unwrap();
537 let mut row0 = matrix.row(0).unwrap().iter();
538 assert_eq!(row0.next(), Some(&"A".to_string()));
539 assert_eq!(row0.next_back(), Some(&"C".to_string()));
540 assert_eq!(row0.next(), Some(&"B".to_string()));
541 assert_eq!(row0.next(), None);
542 assert_eq!(row0.next_back(), None);
543 }
544
545 #[test]
546 fn row_iterator_reverse_passes_forward() {
547 let opts = ascii_parse_opts();
548 let matrix = opts.parse_matrix::<String, u8>("ABC\nDEF", |x| x.to_string()).unwrap();
549 let mut row1 = matrix.row(1).unwrap().iter();
550 assert_eq!(row1.next(), Some(&"D".to_string()));
551 assert_eq!(row1.next_back(), Some(&"F".to_string()));
552 assert_eq!(row1.next_back(), Some(&"E".to_string()));
553 assert_eq!(row1.next_back(), None);
554 assert_eq!(row1.next(), None);
555 }
556
557 #[test]
558 fn rows_iterator_forward() {
559 let opts = ascii_parse_opts();
560 let matrix = opts.parse_matrix::<String, u8>("ABC\nDEF", |x| x.to_string()).unwrap();
561 let mut rows = matrix.rows();
562 let row1 = rows.next().unwrap();
563 let values1: Vec<&String> = row1.iter().collect();
564 assert_eq!(values1, vec!["A", "B", "C"]);
565 let row2 = rows.next().unwrap();
566 let values2: Vec<&String> = row2.iter().collect();
567 assert_eq!(values2, vec!["D", "E", "F"]);
568 assert!(rows.next().is_none());
569 }
570
571 #[test]
572 fn rows_iterator_backward() {
573 let opts = ascii_parse_opts();
574 let matrix = opts.parse_matrix::<String, u8>("ABC\nDEF", |x| x.to_string()).unwrap();
575 let mut rows = matrix.rows().rev();
576 let row1 = rows.next().unwrap();
577 let values1: Vec<&String> = row1.iter().collect();
578 assert_eq!(values1, vec!["D", "E", "F"]);
579 let row2 = rows.next().unwrap();
580 let values2: Vec<&String> = row2.iter().collect();
581 assert_eq!(values2, vec!["A", "B", "C"]);
582 assert!(rows.next().is_none());
583 }
584
585
586 #[test]
587 fn column_iterator_forward_only() {
588 let opts = ascii_parse_opts();
589 let matrix = opts.parse_matrix::<String, u8>("ABC\nDEF", |x| x.to_string()).unwrap();
590 let column0 = matrix.column(0).unwrap().iter();
591 let values: Vec<&String> = column0.collect();
592 assert_eq!(values, vec!["A", "D"]);
593 }
594
595 #[test]
596 fn column_iterator_reverse_only() {
597 let opts = ascii_parse_opts();
598 let matrix = opts.parse_matrix::<String, u8>("ABC\nDEF", |x| x.to_string()).unwrap();
599 let column0 = matrix.column(0).unwrap().iter().rev();
600 let values: Vec<&String> = column0.collect();
601 assert_eq!(values, vec!["D", "A"]);
602 }
603
604 #[test]
605 fn column_iterator_forward_passes_reverse() {
606 let opts = ascii_parse_opts();
607 let matrix = opts.parse_matrix::<String, u8>("ABC\nDEF", |x| x.to_string()).unwrap();
608 let mut column0 = matrix.column(0).unwrap().iter();
609 assert_eq!(column0.next(), Some(&"A".to_string()));
610 assert_eq!(column0.next_back(), Some(&"D".to_string()));
611 assert_eq!(column0.next(), None);
612 assert_eq!(column0.next_back(), None);
613 }
614
615 #[test]
616 fn column_iterator_reverse_passes_forward() {
617 let opts = ascii_parse_opts();
618 let matrix = opts.parse_matrix::<String, u8>("ABC\nDEF", |x| x.to_string()).unwrap();
619 let mut column1 = matrix.column(1).unwrap().iter();
620 assert_eq!(column1.next(), Some(&"B".to_string()));
621 assert_eq!(column1.next_back(), Some(&"E".to_string()));
622 assert_eq!(column1.next_back(), None);
623 assert_eq!(column1.next(), None);
624 }
625
626 #[test]
627 fn columns_iterator_forward() {
628 let opts = ascii_parse_opts();
629 let matrix = opts.parse_matrix::<String, u8>("ABC\nDEF", |x| x.to_string()).unwrap();
630 let mut columns = matrix.columns();
631 let column1 = columns.next().unwrap();
632 let values1: Vec<&String> = column1.iter().collect();
633 assert_eq!(values1, vec!["A", "D"]);
634 let column2 = columns.next().unwrap();
635 let values2: Vec<&String> = column2.iter().collect();
636 assert_eq!(values2, vec!["B", "E"]);
637 let column3 = columns.next().unwrap();
638 let values3: Vec<&String> = column3.iter().collect();
639 assert_eq!(values3, vec!["C", "F"]);
640 assert!(columns.next().is_none());
641 }
642
643 #[test]
644 fn columns_iterator_backward() {
645 let opts = ascii_parse_opts();
646 let matrix = opts.parse_matrix::<String, u8>("ABC\nDEF", |x| x.to_string()).unwrap();
647 let mut columns = matrix.columns().rev();
648 let column1 = columns.next().unwrap();
649 let values1: Vec<&String> = column1.iter().collect();
650 assert_eq!(values1, vec!["C", "F"]);
651 let column2 = columns.next().unwrap();
652 let values2: Vec<&String> = column2.iter().collect();
653 assert_eq!(values2, vec!["B", "E"]);
654 let column3 = columns.next().unwrap();
655 let values3: Vec<&String> = column3.iter().collect();
656 assert_eq!(values3, vec!["A", "D"]);
657 assert!(columns.next().is_none());
658 }
659}
660