tabled/settings/location/
by_condition.rs

1use crate::{
2    grid::config::Entity,
3    grid::{
4        config::Position,
5        records::{ExactRecords, PeekableRecords, Records},
6    },
7    settings::location::Location,
8    settings::object::Object,
9};
10
11/// The structure is an implementation of [`Location`] to search for cells with a specified condition.
12#[derive(Debug, Clone, Copy, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
13pub struct ByCondition<F>(F);
14
15impl<F> ByCondition<F> {
16    /// Constructs a new object of the structure.
17    pub fn new(search: F) -> Self
18    where
19        F: Fn(&str) -> bool,
20    {
21        Self(search)
22    }
23}
24
25impl<F, R> Location<R> for ByCondition<F>
26where
27    F: Fn(&str) -> bool,
28    R: Records + ExactRecords + PeekableRecords,
29{
30    type Coordinate = Position;
31    type IntoIter = Vec<Position>;
32
33    fn locate(&mut self, records: &R) -> Self::IntoIter {
34        // todo: can be optimized by creating Iterator
35        let cond = &self.0;
36
37        let mut out = vec![];
38        for row in 0..records.count_rows() {
39            for col in 0..records.count_columns() {
40                let text = records.get_text((row, col).into());
41                if cond(text) {
42                    out.push((row, col).into());
43                }
44            }
45        }
46
47        out
48    }
49}
50
51impl<F, R> Object<R> for ByCondition<F>
52where
53    F: Fn(&str) -> bool,
54    R: Records + ExactRecords + PeekableRecords,
55{
56    type Iter = std::vec::IntoIter<Entity>;
57
58    fn cells(&self, records: &R) -> Self::Iter {
59        // todo: can be optimized by creating Iterator
60        let cond = &self.0;
61
62        let mut out = vec![];
63        for row in 0..records.count_rows() {
64            for col in 0..records.count_columns() {
65                let text = records.get_text((row, col).into());
66                if cond(text) {
67                    out.push(Entity::Cell(row, col));
68                }
69            }
70        }
71
72        out.into_iter()
73    }
74}