use std::ops::{Deref, DerefMut};
use super::private::LabelMap;
pub type RowId = u32;
#[derive(Clone, Copy, Debug)]
pub struct RowRef<R, L> {
id: RowId,
row: R,
columns: L,
}
pub trait CellAccessor {
type Target;
fn access(self, pos: usize) -> Option<Self::Target>;
}
impl<R, L> RowRef<R, L>
where
R: CellAccessor,
L: LabelMap,
{
pub(crate) fn new(id: RowId, row: R, label_map: L) -> Self {
Self {
id,
row,
columns: label_map,
}
}
pub(crate) fn map<O: CellAccessor, M: LabelMap>(
self,
mapper: impl FnOnce(R) -> O,
columns: M,
) -> RowRef<O, M> {
RowRef {
id: self.id,
row: mapper(self.row),
columns,
}
}
pub fn id(&self) -> RowId {
self.id
}
pub fn get_if_present(self, column: impl Into<L::Name>) -> Option<R::Target> {
let index = self.columns.position(&column.into())?;
self.row.access(index)
}
pub fn get(self, column: impl Into<L::Name>) -> R::Target {
self.get_if_present(column).expect("no such column")
}
}
impl<R, L> Deref for RowRef<R, L> {
type Target = R;
fn deref(&self) -> &Self::Target {
&self.row
}
}
impl<R, L> DerefMut for RowRef<R, L> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.row
}
}