tabled/settings/location/
by_column_name.rs

1use crate::{
2    grid::config::Entity,
3    grid::records::{ExactRecords, PeekableRecords, Records},
4    settings::location::Location,
5    settings::object::Object,
6};
7
8/// The structure is an implementation of [`Location`] to search for a column by it's name.
9/// A name is considered be a value in a first row.
10///
11/// So even if in reality there's no header, the first row will be considered to be one.
12#[derive(Debug, Clone, Copy, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
13pub struct ByColumnName<S>(S);
14
15impl<S> ByColumnName<S> {
16    /// Constructs a new object of the structure.
17    pub fn new(text: S) -> Self
18    where
19        S: AsRef<str>,
20    {
21        Self(text)
22    }
23}
24
25impl<R, S> Location<R> for ByColumnName<S>
26where
27    S: AsRef<str>,
28    R: Records + ExactRecords + PeekableRecords,
29{
30    type Coordinate = usize;
31    type IntoIter = Vec<usize>;
32
33    fn locate(&mut self, records: &R) -> Self::IntoIter {
34        // todo: can be optimized by creating Iterator
35        (0..records.count_columns())
36            .filter(|col| records.get_text((0, *col).into()) == self.0.as_ref())
37            .collect::<Vec<_>>()
38    }
39}
40
41impl<S, R> Object<R> for ByColumnName<S>
42where
43    S: AsRef<str>,
44    R: Records + PeekableRecords + ExactRecords,
45{
46    type Iter = std::vec::IntoIter<Entity>;
47
48    fn cells(&self, records: &R) -> Self::Iter {
49        // todo: can be optimized by creating Iterator
50        (0..records.count_columns())
51            .filter(|col| records.get_text((0, *col).into()) == self.0.as_ref())
52            .map(Entity::Column)
53            .collect::<Vec<_>>()
54            .into_iter()
55    }
56}