1use std::ops::{RangeBounds, RangeFull};
2
3use crate::{
4 grid::config::Entity,
5 grid::records::{ExactRecords, Records},
6 settings::object::{cell::EntityOnce, Object},
7};
8
9use super::util::bounds_to_usize;
10
11/// This structure represents a sub table of [`Table`].
12///
13/// [`Table`]: crate::Table
14#[derive(Debug)]
15pub struct Segment<C, R> {
16 columns: C,
17 rows: R,
18}
19
20impl Segment<RangeFull, RangeFull> {
21 /// Returns a table segment on which are present all cells.
22 pub fn all() -> SegmentAll {
23 SegmentAll
24 }
25}
26
27impl<C, R> Segment<C, R>
28where
29 C: RangeBounds<usize>,
30 R: RangeBounds<usize>,
31{
32 /// This function builds a [`Segment`].
33 pub fn new(rows: R, columns: C) -> Self {
34 Self { columns, rows }
35 }
36}
37
38impl<I, C, R> Object<I> for Segment<C, R>
39where
40 C: RangeBounds<usize>,
41 R: RangeBounds<usize>,
42 I: Records + ExactRecords,
43{
44 type Iter = SectorIter;
45
46 fn cells(&self, records: &I) -> Self::Iter {
47 let start: Bound<&usize> = self.rows.start_bound();
48 let end: Bound<&usize> = self.rows.end_bound();
49 let max: usize = records.count_rows();
50 let (rows_start: usize, rows_end: usize) = bounds_to_usize(left:start, right:end, count_elements:max);
51
52 let start: Bound<&usize> = self.columns.start_bound();
53 let end: Bound<&usize> = self.columns.end_bound();
54 let max: usize = records.count_columns();
55 let (cols_start: usize, cols_end: usize) = bounds_to_usize(left:start, right:end, count_elements:max);
56
57 SectorIter::new(rows_start, rows_end, cols_start, cols_end)
58 }
59}
60
61/// This is a segment which contains all cells on the table.
62///
63/// Can be created from [`Segment::all`].
64#[derive(Debug)]
65pub struct SegmentAll;
66
67impl<I> Object<I> for SegmentAll {
68 type Iter = EntityOnce;
69
70 fn cells(&self, _: &I) -> Self::Iter {
71 EntityOnce::new(entity:Some(Entity::Global))
72 }
73}
74
75/// An [`Iterator`] which goes goes over all cell in a sector in a [`Table`].
76///
77/// [`Table`]: crate::Table
78#[derive(Debug)]
79pub struct SectorIter {
80 iter: SectorCellsIter,
81}
82
83impl SectorIter {
84 const fn new(rows_start: usize, rows_end: usize, cols_start: usize, cols_end: usize) -> Self {
85 Self {
86 iter: SectorCellsIter::new(rows_start, rows_end, cols_start, cols_end),
87 }
88 }
89}
90
91impl Iterator for SectorIter {
92 type Item = Entity;
93
94 fn next(&mut self) -> Option<Self::Item> {
95 let (row: usize, col: usize) = self.iter.next()?;
96 Some(Entity::Cell(row, col))
97 }
98}
99
100#[derive(Debug)]
101pub(crate) struct SectorCellsIter {
102 rows_end: usize,
103 cols_start: usize,
104 cols_end: usize,
105 row: usize,
106 col: usize,
107}
108
109impl SectorCellsIter {
110 /// Create an iterator from 1st row to last from 1st col to last.
111 pub(crate) const fn new(
112 rows_start: usize,
113 rows_end: usize,
114 cols_start: usize,
115 cols_end: usize,
116 ) -> Self {
117 Self {
118 rows_end,
119 cols_start,
120 cols_end,
121 row: rows_start,
122 col: cols_start,
123 }
124 }
125}
126
127impl Iterator for SectorCellsIter {
128 type Item = (usize, usize);
129
130 fn next(&mut self) -> Option<Self::Item> {
131 if self.row >= self.rows_end {
132 return None;
133 }
134
135 if self.col >= self.cols_end {
136 return None;
137 }
138
139 let row = self.row;
140 let col = self.col;
141
142 self.col += 1;
143
144 if self.col == self.cols_end {
145 self.row += 1;
146 self.col = self.cols_start;
147 }
148
149 Some((row, col))
150 }
151}
152