1use crate::{
2 grid::config::Entity,
3 grid::records::{ExactRecords, Records},
4 settings::object::Object,
5};
6
7/// Frame includes cells which are on the edges of each side.
8/// Therefore it's [`Object`] implementation returns a subset of cells which are present in frame.
9#[derive(Debug)]
10pub struct Frame;
11
12impl<I> Object<I> for Frame
13where
14 I: Records + ExactRecords,
15{
16 type Iter = FrameIter;
17
18 fn cells(&self, records: &I) -> Self::Iter {
19 FrameIter::new(records.count_rows(), records.count_columns())
20 }
21}
22
23/// An [`Iterator`] which goes goes over all cell on a frame of a [`Table`].
24///
25/// [`Table`]: crate::Table
26#[derive(Debug)]
27pub struct FrameIter {
28 rows: usize,
29 cols: usize,
30 row: usize,
31 col: usize,
32}
33
34impl FrameIter {
35 const fn new(count_rows: usize, count_columns: usize) -> Self {
36 Self {
37 rows: count_rows,
38 cols: count_columns,
39 row: 0,
40 col: 0,
41 }
42 }
43}
44
45impl Iterator for FrameIter {
46 type Item = Entity;
47
48 fn next(&mut self) -> Option<Self::Item> {
49 if self.cols == 0 || self.rows == 0 {
50 return None;
51 }
52
53 if self.row == self.rows {
54 return None;
55 }
56
57 let row = self.row;
58 let col = self.col;
59
60 self.col += 1;
61
62 if self.col == self.cols {
63 self.row += 1;
64 self.col = 0;
65 }
66
67 Some(Entity::Cell(row, col))
68 }
69}
70