1use crate::{
2 lang::elements::{
3 InlineElement, InlineElementContainer, IntoChildren, Located,
4 },
5 StrictEq,
6};
7use derive_more::{Constructor, Display, Error, From, IntoIterator};
8use serde::{Deserialize, Serialize};
9use std::collections::HashMap;
10use std::{num::ParseIntError, str::FromStr};
11
12#[derive(
14 Constructor,
15 Copy,
16 Clone,
17 Debug,
18 Eq,
19 PartialEq,
20 Hash,
21 Display,
22 Serialize,
23 Deserialize,
24)]
25#[display(fmt = "{},{}", row, col)]
26pub struct CellPos {
27 pub row: usize,
29
30 pub col: usize,
32}
33
34#[derive(Debug, Display, Error)]
35pub enum ParseCellPosError {
36 TooFewItems,
37 TooManyItems,
38 BadRow(#[error(source)] ParseIntError),
39 BadCol(#[error(source)] ParseIntError),
40}
41
42impl FromStr for CellPos {
43 type Err = ParseCellPosError;
44
45 fn from_str(s: &str) -> Result<Self, Self::Err> {
47 let mut iter = s.split(',');
48 let row_str = iter.next();
49 let col_str = iter.next();
50
51 if iter.next().is_some() {
52 Err(ParseCellPosError::TooManyItems)
53 } else {
54 match (row_str, col_str) {
55 (Some(row_str), Some(col_str)) => {
56 let row: usize = row_str
57 .trim()
58 .parse()
59 .map_err(ParseCellPosError::BadRow)?;
60 let col: usize = col_str
61 .trim()
62 .parse()
63 .map_err(ParseCellPosError::BadCol)?;
64 Ok(Self { row, col })
65 }
66 _ => Err(ParseCellPosError::TooFewItems),
67 }
68 }
69 }
70}
71
72#[derive(Clone, Debug, Eq, PartialEq, IntoIterator, Serialize, Deserialize)]
73pub struct Table<'a> {
74 #[into_iterator(owned, ref, ref_mut)]
77 #[serde(with = "serde_with::rust::map_as_tuple_list")]
78 cells: HashMap<CellPos, Located<Cell<'a>>>,
79
80 row_cnt: usize,
82
83 col_cnt: usize,
85
86 pub centered: bool,
88}
89
90impl Table<'_> {
91 pub fn to_borrowed(&self) -> Table {
92 Table {
93 cells: self
94 .cells
95 .iter()
96 .map(|(k, v)| (*k, v.as_ref().map(Cell::to_borrowed)))
97 .collect(),
98 row_cnt: self.row_cnt,
99 col_cnt: self.col_cnt,
100 centered: self.centered,
101 }
102 }
103
104 pub fn into_owned(self) -> Table<'static> {
105 Table {
106 cells: self
107 .cells
108 .into_iter()
109 .map(|(k, v)| (k, v.map(Cell::into_owned)))
110 .collect(),
111 row_cnt: self.row_cnt,
112 col_cnt: self.col_cnt,
113 centered: self.centered,
114 }
115 }
116}
117
118impl<'a> Table<'a> {
119 pub fn new<I: IntoIterator<Item = (CellPos, Located<Cell<'a>>)>>(
120 cells: I,
121 centered: bool,
122 ) -> Self {
123 let cells: HashMap<CellPos, Located<Cell>> =
124 cells.into_iter().collect();
125 let (max_row, max_col) = cells.keys().fold((0, 0), |acc, pos| {
126 (
127 std::cmp::max(acc.0, pos.row + 1),
128 std::cmp::max(acc.1, pos.col + 1),
129 )
130 });
131
132 Self {
133 cells,
134 row_cnt: max_row,
135 col_cnt: max_col,
136 centered,
137 }
138 }
139
140 pub fn header_rows(&self) -> iter::HeaderRows<'_, 'a> {
144 iter::HeaderRows::new(self)
145 }
146
147 pub fn body_rows(&self) -> iter::BodyRows<'_, 'a> {
151 iter::BodyRows::new(self)
152 }
153
154 pub fn has_header_rows(&self) -> bool {
156 self.header_rows().next().is_some()
157 }
158
159 pub fn has_body_rows(&self) -> bool {
161 self.body_rows().next().is_some()
162 }
163
164 #[inline]
166 pub fn has_divider_row(&self) -> bool {
167 self.get_divider_row_index().is_some()
168 }
169
170 pub fn get_divider_row_index(&self) -> Option<usize> {
173 self.rows().enumerate().find_map(|(idx, row)| {
174 if row.is_divider_row() {
175 Some(idx)
176 } else {
177 None
178 }
179 })
180 }
181
182 pub fn get_column_alignment(&self, col: usize) -> ColumnAlign {
187 self.column(col)
188 .find_map(|cell| cell.get_align().copied())
189 .unwrap_or_default()
190 }
191
192 #[inline]
194 pub fn row_cnt(&self) -> usize {
195 self.row_cnt
196 }
197
198 #[inline]
200 pub fn col_cnt(&self) -> usize {
201 self.col_cnt
202 }
203
204 #[inline]
206 pub fn len(&self) -> usize {
207 self.cells.len()
208 }
209
210 #[inline]
213 pub fn is_empty(&self) -> bool {
214 self.cells.is_empty()
215 }
216
217 #[inline]
219 pub fn as_data(&self) -> &HashMap<CellPos, Located<Cell<'a>>> {
220 &self.cells
221 }
222
223 pub fn rows(&self) -> iter::Rows<'_, 'a> {
225 iter::Rows::new(self)
226 }
227
228 pub fn row(&self, idx: usize) -> iter::Row<'_, 'a> {
230 iter::Row::new(self, idx, 0)
231 }
232
233 pub fn into_row(self, idx: usize) -> iter::IntoRow<'a> {
235 iter::IntoRow::new(self, idx, 0)
236 }
237
238 pub fn columns(&self) -> iter::Columns<'_, 'a> {
240 iter::Columns::new(self)
241 }
242
243 pub fn column(&self, idx: usize) -> iter::Column<'_, 'a> {
245 iter::Column::new(self, 0, idx)
246 }
247
248 pub fn into_column(self, idx: usize) -> iter::IntoColumn<'a> {
250 iter::IntoColumn::new(self, 0, idx)
251 }
252
253 pub fn cells(&self) -> iter::Cells<'_, 'a> {
257 iter::Cells::new(self)
258 }
259
260 pub fn into_cells(self) -> iter::IntoCells<'a> {
264 iter::IntoCells::new(self)
265 }
266
267 pub fn get_cell(
269 &self,
270 row: usize,
271 col: usize,
272 ) -> Option<&Located<Cell<'a>>> {
273 self.cells.get(&CellPos { row, col })
274 }
275
276 pub fn get_mut_cell(
278 &mut self,
279 row: usize,
280 col: usize,
281 ) -> Option<&mut Located<Cell<'a>>> {
282 self.cells.get_mut(&CellPos { row, col })
283 }
284
285 pub fn get_cell_rowspan(&self, row: usize, col: usize) -> usize {
292 let mut it = self.column(col).skip(row);
293
294 match it.next() {
297 Some(cell) if cell.is_content() => {}
298 _ => return 0,
299 }
300
301 it.take_while(|cell| {
302 matches!(cell.get_span().copied(), Some(CellSpan::FromAbove))
303 })
304 .count()
305 + 1
306 }
307
308 pub fn get_cell_colspan(&self, row: usize, col: usize) -> usize {
315 let mut it = self.row(row).skip(col);
316
317 match it.next() {
320 Some(cell) if cell.is_content() => {}
321 _ => return 0,
322 }
323
324 it.take_while(|cell| {
325 matches!(cell.get_span().copied(), Some(CellSpan::FromLeft))
326 })
327 .count()
328 + 1
329 }
330}
331
332impl<'a> IntoChildren for Table<'a> {
333 type Child = Located<InlineElement<'a>>;
334
335 fn into_children(self) -> Vec<Self::Child> {
336 self.cells
337 .into_iter()
338 .flat_map(|(_, x)| x.into_inner().into_children())
339 .collect()
340 }
341}
342
343impl<'a> StrictEq for Table<'a> {
344 fn strict_eq(&self, other: &Self) -> bool {
346 self.centered == other.centered
347 && self.cells.len() == other.cells.len()
348 && self.cells.iter().all(|(k, v)| {
349 other.cells.get(k).map_or(false, |v2| v.strict_eq(v2))
350 })
351 }
352}
353
354#[derive(Clone, Debug, From, Eq, PartialEq, Hash, Serialize, Deserialize)]
357pub enum Cell<'a> {
358 Content(InlineElementContainer<'a>),
359 Span(CellSpan),
360 Align(ColumnAlign),
361}
362
363impl Cell<'_> {
364 pub fn to_borrowed(&self) -> Cell {
365 match self {
366 Self::Content(x) => Cell::Content(x.to_borrowed()),
367 Self::Span(x) => Cell::Span(*x),
368 Self::Align(x) => Cell::Align(*x),
369 }
370 }
371
372 pub fn into_owned(self) -> Cell<'static> {
373 match self {
374 Self::Content(x) => Cell::Content(x.into_owned()),
375 Self::Span(x) => Cell::Span(x),
376 Self::Align(x) => Cell::Align(x),
377 }
378 }
379}
380
381impl<'a> Cell<'a> {
382 #[inline]
384 pub fn is_content(&self) -> bool {
385 matches!(self, Cell::Content(_))
386 }
387
388 #[inline]
390 pub fn is_span(&self) -> bool {
391 matches!(self, Cell::Span(_))
392 }
393
394 #[inline]
396 pub fn is_align(&self) -> bool {
397 matches!(self, Cell::Align(_))
398 }
399
400 #[inline]
402 pub fn get_content(&self) -> Option<&InlineElementContainer<'a>> {
403 match self {
404 Self::Content(x) => Some(x),
405 _ => None,
406 }
407 }
408
409 #[inline]
411 pub fn get_span(&self) -> Option<&CellSpan> {
412 match self {
413 Self::Span(x) => Some(x),
414 _ => None,
415 }
416 }
417
418 #[inline]
421 pub fn get_align(&self) -> Option<&ColumnAlign> {
422 match self {
423 Self::Align(x) => Some(x),
424 _ => None,
425 }
426 }
427}
428
429impl<'a> IntoChildren for Cell<'a> {
430 type Child = Located<InlineElement<'a>>;
431
432 fn into_children(self) -> Vec<Self::Child> {
433 match self {
434 Self::Content(x) => x.into_children(),
435 _ => vec![],
436 }
437 }
438}
439
440impl<'a> StrictEq for Cell<'a> {
441 fn strict_eq(&self, other: &Self) -> bool {
443 match (self, other) {
444 (Self::Content(x), Self::Content(y)) => x.strict_eq(y),
445 (Self::Span(x), Self::Span(y)) => x == y,
446 (Self::Align(x), Self::Align(y)) => x == y,
447 _ => false,
448 }
449 }
450}
451
452#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)]
453pub enum CellSpan {
454 FromLeft,
455 FromAbove,
456}
457
458impl StrictEq for CellSpan {
459 fn strict_eq(&self, other: &Self) -> bool {
461 self == other
462 }
463}
464
465#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)]
466pub enum ColumnAlign {
467 Left,
468 Center,
469 Right,
470}
471
472impl Default for ColumnAlign {
473 fn default() -> Self {
475 Self::Left
476 }
477}
478
479impl StrictEq for ColumnAlign {
480 fn strict_eq(&self, other: &Self) -> bool {
482 self == other
483 }
484}
485
486pub mod iter {
487 use super::{Cell, CellPos, Located, Table};
488 use derive_more::Constructor;
489
490 pub struct Rows<'a, 'b> {
491 table: &'a Table<'b>,
492 idx: usize,
493 }
494
495 impl<'a, 'b> Rows<'a, 'b> {
496 pub fn new(table: &'a Table<'b>) -> Self {
499 Self { table, idx: 0 }
500 }
501
502 pub fn empty(table: &'a Table<'b>) -> Self {
504 Self {
505 table,
506 idx: table.row_cnt(),
507 }
508 }
509
510 pub fn has_content(&self) -> bool {
513 let mut rows = Rows {
514 table: self.table,
515 idx: self.idx,
516 };
517
518 rows.any(|row| row.has_content())
519 }
520 }
521
522 impl<'a, 'b> Iterator for Rows<'a, 'b> {
523 type Item = Row<'a, 'b>;
524
525 fn next(&mut self) -> Option<Self::Item> {
526 if self.idx < self.table.row_cnt() {
527 let row = Row::new(self.table, self.idx, 0);
528 self.idx += 1;
529 Some(row)
530 } else {
531 None
532 }
533 }
534
535 fn size_hint(&self) -> (usize, Option<usize>) {
536 let remaining = self.table.row_cnt() - self.idx;
537 (remaining, Some(remaining))
538 }
539 }
540
541 pub struct HeaderRows<'a, 'b> {
542 table: &'a Table<'b>,
543 idx: usize,
544 len: usize,
545 }
546
547 impl<'a, 'b> HeaderRows<'a, 'b> {
548 pub fn new(table: &'a Table<'b>) -> Self {
551 Self {
552 table,
553 idx: 0,
554 len: table.get_divider_row_index().unwrap_or_default(),
555 }
556 }
557
558 pub fn has_content(&self) -> bool {
561 let mut rows = HeaderRows {
562 table: self.table,
563 idx: self.idx,
564 len: self.len,
565 };
566
567 rows.any(|row| row.has_content())
568 }
569 }
570
571 impl<'a, 'b> Iterator for HeaderRows<'a, 'b> {
572 type Item = Row<'a, 'b>;
573
574 fn next(&mut self) -> Option<Self::Item> {
575 while self.idx < self.len {
578 let row = Row::new(self.table, self.idx, 0);
579 self.idx += 1;
580
581 if !row.is_divider_row() {
582 return Some(row);
583 }
584 }
585
586 None
587 }
588
589 fn size_hint(&self) -> (usize, Option<usize>) {
590 let remaining = self.len - self.idx;
591 (remaining, Some(remaining))
592 }
593 }
594
595 pub struct BodyRows<'a, 'b> {
596 table: &'a Table<'b>,
597 idx: usize,
598 }
599
600 impl<'a, 'b> BodyRows<'a, 'b> {
601 pub fn new(table: &'a Table<'b>) -> Self {
604 Self {
605 table,
606 idx: table.get_divider_row_index().unwrap_or_default(),
607 }
608 }
609
610 pub fn has_content(&self) -> bool {
613 let mut rows = BodyRows {
614 table: self.table,
615 idx: self.idx,
616 };
617
618 rows.any(|row| row.has_content())
619 }
620 }
621
622 impl<'a, 'b> Iterator for BodyRows<'a, 'b> {
623 type Item = Row<'a, 'b>;
624
625 fn next(&mut self) -> Option<Self::Item> {
626 while self.idx < self.table.row_cnt() {
629 let row = Row::new(self.table, self.idx, 0);
630 self.idx += 1;
631
632 if !row.is_divider_row() {
633 return Some(row);
634 }
635 }
636
637 None
638 }
639
640 fn size_hint(&self) -> (usize, Option<usize>) {
641 let remaining = self.table.row_cnt() - self.idx;
642 (remaining, Some(remaining))
643 }
644 }
645
646 #[derive(Constructor)]
647 pub struct Row<'a, 'b> {
648 table: &'a Table<'b>,
649 row: usize,
650 col: usize,
651 }
652
653 impl<'a, 'b> Row<'a, 'b> {
654 pub fn is_divider_row(&self) -> bool {
655 self.table
658 .get_cell(self.row, 0)
659 .map_or(false, |cell| cell.is_align())
660 }
661
662 pub fn zip_with_position(
663 self,
664 ) -> impl Iterator<Item = (CellPos, &'a Located<Cell<'b>>)> {
665 let pos = CellPos::new(self.row, self.col);
666 self.map(move |cell| (pos, cell))
667 }
668
669 pub fn has_content(&self) -> bool {
671 let mut row = Row {
672 table: self.table,
673 row: self.row,
674 col: self.col,
675 };
676
677 row.any(|cell| cell.is_content())
678 }
679 }
680
681 impl<'a, 'b> Iterator for Row<'a, 'b> {
682 type Item = &'a Located<Cell<'b>>;
683
684 fn next(&mut self) -> Option<Self::Item> {
685 let cell = self.table.get_cell(self.row, self.col);
686 if cell.is_some() {
687 self.col += 1;
688 }
689 cell
690 }
691
692 fn size_hint(&self) -> (usize, Option<usize>) {
693 let remaining = self.table.col_cnt() - self.col;
694 (remaining, Some(remaining))
695 }
696 }
697
698 #[derive(Constructor)]
699 pub struct IntoRow<'a> {
700 table: Table<'a>,
701 row: usize,
702 col: usize,
703 }
704
705 impl<'a> IntoRow<'a> {
706 pub fn is_divider_row(&self) -> bool {
707 self.table
710 .get_cell(self.row, 0)
711 .map_or(false, |cell| cell.is_align())
712 }
713
714 pub fn zip_with_position(
715 self,
716 ) -> impl Iterator<Item = (CellPos, Located<Cell<'a>>)> {
717 let pos = CellPos::new(self.row, self.col);
718 self.map(move |cell| (pos, cell))
719 }
720
721 pub fn has_content(&self) -> bool {
723 Row::from(self).has_content()
724 }
725 }
726
727 impl<'a, 'b> From<&'a IntoRow<'b>> for Row<'a, 'b> {
728 fn from(it: &'a IntoRow<'b>) -> Self {
729 Self {
730 table: &it.table,
731 row: it.row,
732 col: it.col,
733 }
734 }
735 }
736
737 impl<'a> Iterator for IntoRow<'a> {
738 type Item = Located<Cell<'a>>;
739
740 fn next(&mut self) -> Option<Self::Item> {
741 let cell =
742 self.table.cells.remove(&CellPos::new(self.row, self.col));
743 if cell.is_some() {
744 self.col += 1;
745 }
746 cell
747 }
748
749 fn size_hint(&self) -> (usize, Option<usize>) {
750 let remaining = self.table.col_cnt() - self.col;
751 (remaining, Some(remaining))
752 }
753 }
754
755 pub struct Columns<'a, 'b> {
756 table: &'a Table<'b>,
757 idx: usize,
758 }
759
760 impl<'a, 'b> Columns<'a, 'b> {
761 pub fn new(table: &'a Table<'b>) -> Self {
764 Self { table, idx: 0 }
765 }
766
767 pub fn empty(table: &'a Table<'b>) -> Self {
769 Self {
770 table,
771 idx: table.col_cnt(),
772 }
773 }
774
775 pub fn has_content(&self) -> bool {
778 let mut columns = Columns {
779 table: self.table,
780 idx: self.idx,
781 };
782
783 columns.any(|column| column.has_content())
784 }
785 }
786
787 impl<'a, 'b> Iterator for Columns<'a, 'b> {
788 type Item = Column<'a, 'b>;
789
790 fn next(&mut self) -> Option<Self::Item> {
791 if self.idx < self.table.col_cnt() {
792 let col = Column::new(self.table, self.idx, 0);
793 self.idx += 1;
794 Some(col)
795 } else {
796 None
797 }
798 }
799
800 fn size_hint(&self) -> (usize, Option<usize>) {
801 let remaining = self.table.col_cnt() - self.idx;
802 (remaining, Some(remaining))
803 }
804 }
805
806 #[derive(Constructor)]
807 pub struct Column<'a, 'b> {
808 table: &'a Table<'b>,
809 row: usize,
810 col: usize,
811 }
812
813 impl<'a, 'b> Column<'a, 'b> {
814 pub fn zip_with_position(
815 self,
816 ) -> impl Iterator<Item = (CellPos, &'a Located<Cell<'b>>)> {
817 let pos = CellPos::new(self.row, self.col);
818 self.map(move |cell| (pos, cell))
819 }
820
821 pub fn has_content(&self) -> bool {
823 let mut column = Column {
824 table: self.table,
825 row: self.row,
826 col: self.col,
827 };
828
829 column.any(|cell| cell.is_content())
830 }
831 }
832
833 impl<'a, 'b> Iterator for Column<'a, 'b> {
834 type Item = &'a Located<Cell<'b>>;
835
836 fn next(&mut self) -> Option<Self::Item> {
837 let cell = self.table.get_cell(self.row, self.col);
838 if cell.is_some() {
839 self.row += 1;
840 }
841 cell
842 }
843
844 fn size_hint(&self) -> (usize, Option<usize>) {
845 let remaining = self.table.row_cnt() - self.row;
846 (remaining, Some(remaining))
847 }
848 }
849
850 #[derive(Constructor)]
851 pub struct IntoColumn<'a> {
852 table: Table<'a>,
853 row: usize,
854 col: usize,
855 }
856
857 impl<'a> IntoColumn<'a> {
858 pub fn zip_with_position(
859 self,
860 ) -> impl Iterator<Item = (CellPos, Located<Cell<'a>>)> {
861 let pos = CellPos::new(self.row, self.col);
862 self.map(move |cell| (pos, cell))
863 }
864
865 pub fn has_content(&self) -> bool {
867 Column::from(self).has_content()
868 }
869 }
870
871 impl<'a, 'b> From<&'a IntoColumn<'b>> for Column<'a, 'b> {
872 fn from(it: &'a IntoColumn<'b>) -> Self {
873 Self {
874 table: &it.table,
875 row: it.row,
876 col: it.col,
877 }
878 }
879 }
880
881 impl<'a> Iterator for IntoColumn<'a> {
882 type Item = Located<Cell<'a>>;
883
884 fn next(&mut self) -> Option<Self::Item> {
885 let cell =
886 self.table.cells.remove(&CellPos::new(self.row, self.col));
887 if cell.is_some() {
888 self.row += 1;
889 }
890 cell
891 }
892
893 fn size_hint(&self) -> (usize, Option<usize>) {
894 let remaining = self.table.row_cnt() - self.row;
895 (remaining, Some(remaining))
896 }
897 }
898
899 pub struct Cells<'a, 'b> {
900 table: &'a Table<'b>,
901 row: usize,
902 col: usize,
903 }
904
905 impl<'a, 'b> Cells<'a, 'b> {
906 pub fn new(table: &'a Table<'b>) -> Self {
907 Self {
908 table,
909 row: 0,
910 col: 0,
911 }
912 }
913
914 pub fn zip_with_position(
915 self,
916 ) -> impl Iterator<Item = (CellPos, &'a Located<Cell<'b>>)> {
917 let pos = CellPos::new(self.row, self.col);
918 self.map(move |cell| (pos, cell))
919 }
920
921 pub fn has_content(&self) -> bool {
923 let mut cells = Cells {
924 table: self.table,
925 row: self.row,
926 col: self.col,
927 };
928
929 cells.any(|cell| cell.is_content())
930 }
931 }
932
933 impl<'a, 'b> Iterator for Cells<'a, 'b> {
934 type Item = &'a Located<Cell<'b>>;
935
936 fn next(&mut self) -> Option<Self::Item> {
937 let cell = self.table.get_cell(self.row, self.col);
938
939 if self.col < self.table.col_cnt() {
941 self.col += 1;
942
943 } else if self.row < self.table.row_cnt() {
946 self.row += 1;
947 self.col = 0;
948 }
949
950 cell
951 }
952
953 fn size_hint(&self) -> (usize, Option<usize>) {
954 let remaining =
955 self.table.len() - (self.row * self.table.col_cnt()) - self.col;
956 (remaining, Some(remaining))
957 }
958 }
959
960 pub struct IntoCells<'a> {
961 table: Table<'a>,
962 row: usize,
963 col: usize,
964 }
965
966 impl<'a> IntoCells<'a> {
967 pub fn new(table: Table<'a>) -> Self {
968 Self {
969 table,
970 row: 0,
971 col: 0,
972 }
973 }
974
975 pub fn zip_with_position(
976 self,
977 ) -> impl Iterator<Item = (CellPos, Located<Cell<'a>>)> {
978 let pos = CellPos::new(self.row, self.col);
979 self.map(move |cell| (pos, cell))
980 }
981
982 pub fn has_content(&self) -> bool {
984 Cells::from(self).has_content()
985 }
986 }
987
988 impl<'a, 'b> From<&'a IntoCells<'b>> for Cells<'a, 'b> {
989 fn from(it: &'a IntoCells<'b>) -> Self {
990 Self {
991 table: &it.table,
992 row: it.row,
993 col: it.col,
994 }
995 }
996 }
997
998 impl<'a> Iterator for IntoCells<'a> {
999 type Item = Located<Cell<'a>>;
1000
1001 fn next(&mut self) -> Option<Self::Item> {
1002 let cell =
1003 self.table.cells.remove(&CellPos::new(self.row, self.col));
1004
1005 if self.col < self.table.col_cnt() {
1007 self.col += 1;
1008
1009 } else if self.row < self.table.row_cnt() {
1012 self.row += 1;
1013 self.col = 0;
1014 }
1015
1016 cell
1017 }
1018
1019 fn size_hint(&self) -> (usize, Option<usize>) {
1020 let remaining =
1021 self.table.len() - (self.row * self.table.col_cnt()) - self.col;
1022 (remaining, Some(remaining))
1023 }
1024 }
1025}