tabled/settings/object/
segment.rs1use std::ops::{RangeBounds, RangeFull};
2
3use papergrid::config::Position;
4
5use crate::{
6 grid::config::Entity,
7 grid::records::{ExactRecords, Records},
8 settings::object::{cell::EntityOnce, Object},
9};
10
11use super::util::bounds_to_usize;
12
13#[derive(Debug)]
17pub struct Segment<C, R> {
18 columns: C,
19 rows: R,
20}
21
22impl Segment<RangeFull, RangeFull> {
23 pub fn all() -> SegmentAll {
25 SegmentAll
26 }
27}
28
29impl<C, R> Segment<C, R>
30where
31 C: RangeBounds<usize>,
32 R: RangeBounds<usize>,
33{
34 pub fn new(rows: R, columns: C) -> Self {
36 Self { columns, rows }
37 }
38}
39
40impl<I, C, R> Object<I> for Segment<C, R>
41where
42 C: RangeBounds<usize>,
43 R: RangeBounds<usize>,
44 I: Records + ExactRecords,
45{
46 type Iter = SectorIter;
47
48 fn cells(&self, records: &I) -> Self::Iter {
49 let start = self.rows.start_bound();
50 let end = self.rows.end_bound();
51 let max = records.count_rows();
52 let (rows_start, rows_end) = bounds_to_usize(start, end, max);
53
54 let start = self.columns.start_bound();
55 let end = self.columns.end_bound();
56 let max = records.count_columns();
57 let (cols_start, cols_end) = bounds_to_usize(start, end, max);
58
59 SectorIter::new(rows_start, rows_end, cols_start, cols_end)
60 }
61}
62
63#[derive(Debug)]
67pub struct SegmentAll;
68
69impl<I> Object<I> for SegmentAll {
70 type Iter = EntityOnce;
71
72 fn cells(&self, _: &I) -> Self::Iter {
73 EntityOnce::new(Some(Entity::Global))
74 }
75}
76
77#[derive(Debug)]
81pub struct SectorIter {
82 iter: SectorCellsIter,
83}
84
85impl SectorIter {
86 const fn new(rows_start: usize, rows_end: usize, cols_start: usize, cols_end: usize) -> Self {
87 Self {
88 iter: SectorCellsIter::new(rows_start, rows_end, cols_start, cols_end),
89 }
90 }
91}
92
93impl Iterator for SectorIter {
94 type Item = Entity;
95
96 fn next(&mut self) -> Option<Self::Item> {
97 self.iter.next().map(Into::into)
98 }
99}
100
101#[derive(Debug)]
102pub(crate) struct SectorCellsIter {
103 rows_end: usize,
104 cols_start: usize,
105 cols_end: usize,
106 row: usize,
107 col: usize,
108}
109
110impl SectorCellsIter {
111 pub(crate) const fn new(
113 rows_start: usize,
114 rows_end: usize,
115 cols_start: usize,
116 cols_end: usize,
117 ) -> Self {
118 Self {
119 rows_end,
120 cols_start,
121 cols_end,
122 row: rows_start,
123 col: cols_start,
124 }
125 }
126}
127
128impl Iterator for SectorCellsIter {
129 type Item = Position;
130
131 fn next(&mut self) -> Option<Self::Item> {
132 if self.row >= self.rows_end {
133 return None;
134 }
135
136 if self.col >= self.cols_end {
137 return None;
138 }
139
140 let row = self.row;
141 let col = self.col;
142
143 self.col += 1;
144
145 if self.col == self.cols_end {
146 self.row += 1;
147 self.col = self.cols_start;
148 }
149
150 Some((row, col).into())
151 }
152}