tabled/features/
locator.rsuse std::{
iter::Once,
ops::{Range, RangeBounds},
};
use papergrid::{records::Records, Entity};
use crate::{
object::{
bounds_to_usize, Column, Columns, FirstColumn, FirstRow, LastColumn, LastRow, Object, Row,
Rows,
},
Table,
};
pub trait Locator {
type Coordinate;
type IntoIter: IntoIterator<Item = Self::Coordinate>;
fn locate<R>(&mut self, records: R) -> Self::IntoIter
where
R: Records;
}
impl<B> Locator for Columns<B>
where
B: RangeBounds<usize>,
{
type Coordinate = usize;
type IntoIter = Range<usize>;
fn locate<R>(&mut self, records: R) -> Self::IntoIter
where
R: Records,
{
let (from, to) = bounds_to_usize(
self.get_range().start_bound(),
self.get_range().end_bound(),
records.count_columns(),
);
from..to
}
}
impl Locator for Column {
type Coordinate = usize;
type IntoIter = Once<usize>;
fn locate<R>(&mut self, _: R) -> Self::IntoIter
where
R: Records,
{
std::iter::once((*self).into())
}
}
impl Locator for FirstColumn {
type Coordinate = usize;
type IntoIter = Once<usize>;
fn locate<R>(&mut self, _: R) -> Self::IntoIter
where
R: Records,
{
std::iter::once(0)
}
}
impl Locator for LastColumn {
type Coordinate = usize;
type IntoIter = Once<usize>;
fn locate<R>(&mut self, records: R) -> Self::IntoIter
where
R: Records,
{
if records.count_columns() > 0 {
std::iter::once(records.count_columns() - 1)
} else {
std::iter::once(0)
}
}
}
impl<B> Locator for Rows<B>
where
B: RangeBounds<usize>,
{
type Coordinate = usize;
type IntoIter = Range<usize>;
fn locate<R>(&mut self, records: R) -> Self::IntoIter
where
R: Records,
{
let (from, to) = bounds_to_usize(
self.get_range().start_bound(),
self.get_range().end_bound(),
records.count_columns(),
);
from..to
}
}
impl Locator for Row {
type Coordinate = usize;
type IntoIter = Once<usize>;
fn locate<R>(&mut self, _: R) -> Self::IntoIter
where
R: Records,
{
std::iter::once((*self).into())
}
}
impl Locator for FirstRow {
type Coordinate = usize;
type IntoIter = Once<usize>;
fn locate<R>(&mut self, _: R) -> Self::IntoIter
where
R: Records,
{
std::iter::once(0)
}
}
impl Locator for LastRow {
type Coordinate = usize;
type IntoIter = Once<usize>;
fn locate<R>(&mut self, records: R) -> Self::IntoIter
where
R: Records,
{
if records.count_rows() > 0 {
std::iter::once(records.count_rows() - 1)
} else {
std::iter::once(0)
}
}
}
#[derive(Debug, Clone, Copy)]
pub struct ByColumnName<S>(S);
impl<S> ByColumnName<S> {
pub fn new(text: S) -> Self
where
S: AsRef<str>,
{
Self(text)
}
}
impl<S> Locator for ByColumnName<S>
where
S: AsRef<str>,
{
type Coordinate = usize;
type IntoIter = Vec<usize>;
fn locate<R>(&mut self, records: R) -> Self::IntoIter
where
R: Records,
{
(0..records.count_columns())
.filter(|col| records.get_text((0, *col)) == self.0.as_ref())
.collect::<Vec<_>>()
}
}
impl<S> Object for ByColumnName<S>
where
S: AsRef<str>,
{
type Iter = std::vec::IntoIter<Entity>;
fn cells<R>(&self, table: &Table<R>) -> Self::Iter
where
R: Records,
{
(0..table.count_columns())
.filter(|col| table.get_records().get_text((0, *col)) == self.0.as_ref())
.map(Entity::Column)
.collect::<Vec<_>>()
.into_iter()
}
}