1 | use 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)] |
13 | pub struct ByCondition<F>(F); |
14 | |
15 | impl<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 | |
25 | impl<F, R> Location<R> for ByCondition<F> |
26 | where |
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: &F = &self.0; |
36 | |
37 | let mut out: Vec<(usize, usize)> = vec![]; |
38 | for row: usize in 0..records.count_rows() { |
39 | for col: usize in 0..records.count_columns() { |
40 | let text: &str = records.get_text((row, col)); |
41 | if cond(text) { |
42 | out.push((row, col)); |
43 | } |
44 | } |
45 | } |
46 | |
47 | out |
48 | } |
49 | } |
50 | |
51 | impl<F, R> Object<R> for ByCondition<F> |
52 | where |
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: &F = &self.0; |
61 | |
62 | let mut out: Vec = vec![]; |
63 | for row: usize in 0..records.count_rows() { |
64 | for col: usize in 0..records.count_columns() { |
65 | let text: &str = records.get_text((row, col)); |
66 | if cond(text) { |
67 | out.push(Entity::Cell(row, col)); |
68 | } |
69 | } |
70 | } |
71 | |
72 | out.into_iter() |
73 | } |
74 | } |
75 | |