tabled/settings/location/
by_value.rs1use crate::{
2 grid::{
3 config::Position,
4 records::{ExactRecords, PeekableRecords, Records},
5 },
6 settings::object::{EntityOnce, Object},
7};
8
9#[derive(Debug, Clone, Copy, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
13pub struct ByValue<O, F> {
14 search: O,
15 f: F,
16}
17
18impl<O, F> ByValue<O, F> {
19 pub fn new(search: O, f: F) -> Self
21 where
22 F: Fn(&str, &str) -> bool,
23 {
24 Self { search, f }
25 }
26}
27
28impl<O, F, R> Object<R> for ByValue<O, F>
29where
30 O: Object<R>,
31 F: Fn(&str, &str) -> bool,
32 R: Records + PeekableRecords + ExactRecords,
33{
34 type Iter = EntityOnce;
35
36 fn cells(&self, records: &R) -> Self::Iter {
37 let count_rows = records.count_rows();
38 let count_cols = records.count_columns();
39 let cells = self.search.cells(records);
40
41 let mut last: Option<&str> = None;
42 let mut last_pos: Option<Position> = None;
43
44 for e in cells.into_iter() {
45 for pos in e.iter(count_rows, count_cols) {
46 let text = records.get_text(pos);
47 match last {
48 Some(last_value) => {
49 let take = (self.f)(text, last_value);
50 if take {
51 last = Some(text);
52 last_pos = Some(pos);
53 }
54 }
55 None => {
56 last = Some(text);
57 last_pos = Some(pos);
58 }
59 }
60 }
61 }
62
63 let pos = last_pos.map(|pos| pos.into());
64
65 EntityOnce::new(pos)
66 }
67}