tabled/settings/object/
columns.rs1use std::ops::{Add, RangeBounds, Sub};
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#[derive(Debug)]
15pub struct Columns<R> {
16 range: R,
17}
18
19impl<R> Columns<R> {
20 pub fn new(range: R) -> Self
24 where
25 R: RangeBounds<usize>,
26 {
27 Self { range }
28 }
29
30 pub(crate) fn get_range(&self) -> &R {
31 &self.range
32 }
33}
34
35impl Columns<()> {
36 pub fn one(index: usize) -> Column {
40 Column(index)
41 }
42
43 pub fn first() -> FirstColumn {
47 FirstColumn
48 }
49
50 pub fn last() -> LastColumn {
54 LastColumn
55 }
56}
57
58impl<I, R> Object<I> for Columns<R>
59where
60 R: RangeBounds<usize>,
61 I: Records,
62{
63 type Iter = ColumnsIter;
64
65 fn cells(&self, records: &I) -> Self::Iter {
66 let max = records.count_columns();
67 let start = self.range.start_bound();
68 let end = self.range.end_bound();
69 let (x, y) = bounds_to_usize(start, end, max);
70
71 ColumnsIter::new(x, y)
72 }
73}
74
75#[derive(Debug)]
77pub struct FirstColumn;
78
79impl<I> Object<I> for FirstColumn
80where
81 I: Records + ExactRecords,
82{
83 type Iter = EntityOnce;
84
85 fn cells(&self, records: &I) -> Self::Iter {
86 if records.count_rows() == 0 || records.count_columns() == 0 {
87 return EntityOnce::new(None);
88 }
89
90 EntityOnce::new(Some(Entity::Column(0)))
91 }
92}
93
94impl Add<usize> for FirstColumn {
95 type Output = Column;
96
97 fn add(self, rhs: usize) -> Self::Output {
98 Column(rhs)
99 }
100}
101
102#[derive(Debug)]
104pub struct LastColumn;
105
106impl<I> Object<I> for LastColumn
107where
108 I: Records + ExactRecords,
109{
110 type Iter = EntityOnce;
111
112 fn cells(&self, records: &I) -> Self::Iter {
113 if records.count_rows() == 0 || records.count_columns() == 0 {
114 return EntityOnce::new(None);
115 }
116
117 let col = records.count_columns().saturating_sub(1);
118 EntityOnce::new(Some(Entity::Column(col)))
119 }
120}
121
122impl Sub<usize> for LastColumn {
123 type Output = LastColumnOffset;
124
125 fn sub(self, rhs: usize) -> Self::Output {
126 LastColumnOffset::sub(rhs)
127 }
128}
129
130impl Add<usize> for LastColumn {
131 type Output = LastColumnOffset;
132
133 fn add(self, rhs: usize) -> Self::Output {
134 LastColumnOffset::add(rhs)
135 }
136}
137
138#[derive(Debug, Clone, Copy)]
140pub struct Column(usize);
141
142impl<I> Object<I> for Column {
143 type Iter = EntityOnce;
144
145 fn cells(&self, _: &I) -> Self::Iter {
146 EntityOnce::new(Some(Entity::Column(self.0)))
147 }
148}
149
150impl From<usize> for Column {
151 fn from(i: usize) -> Self {
152 Self(i)
153 }
154}
155
156impl From<Column> for usize {
157 fn from(val: Column) -> Self {
158 val.0
159 }
160}
161
162#[derive(Debug)]
164pub struct LastColumnOffset {
165 offset: usize,
166 sign: bool,
167}
168
169impl LastColumnOffset {
170 fn sub(offset: usize) -> Self {
171 Self {
172 offset,
173 sign: false,
174 }
175 }
176
177 fn add(offset: usize) -> Self {
178 Self { offset, sign: true }
179 }
180}
181
182impl<I> Object<I> for LastColumnOffset
183where
184 I: Records,
185{
186 type Iter = EntityOnce;
187
188 fn cells(&self, records: &I) -> Self::Iter {
189 let count_cols = records.count_columns();
190 if count_cols == 0 {
191 return EntityOnce::new(None);
192 }
193
194 let last_col = count_cols - 1;
195
196 if self.sign {
197 let col = last_col + self.offset;
198 EntityOnce::new(Some(Entity::Column(col)))
199 } else {
200 if self.offset > last_col {
201 return EntityOnce::new(None);
202 }
203
204 let col = last_col - self.offset;
205 EntityOnce::new(Some(Entity::Column(col)))
206 }
207 }
208}
209
210#[derive(Debug)]
214pub struct ColumnsIter {
215 start: usize,
216 end: usize,
217}
218
219impl ColumnsIter {
220 const fn new(start: usize, end: usize) -> Self {
221 Self { start, end }
222 }
223}
224
225impl Iterator for ColumnsIter {
226 type Item = Entity;
227
228 fn next(&mut self) -> Option<Self::Item> {
229 if self.start >= self.end {
230 return None;
231 }
232
233 let col = self.start;
234 self.start += 1;
235
236 Some(Entity::Column(col))
237 }
238}