use crate::{Cell, Label, Value};
use crate::{ColumnMap, FromCell};
use std::borrow::Borrow;
use std::marker::PhantomData;
use std::ops::{Deref, DerefMut, Index};
#[derive(Debug, Clone, PartialEq)]
pub struct Row<'b> {
pub(crate) id: usize,
pub(crate) cells: Vec<Cell<'b>>,
}
#[derive(Clone, Copy, Debug)]
pub struct RowRef<'t, 'tb, C = &'t Cell<'tb>> {
row: &'t Row<'tb>,
columns: &'t ColumnMap,
_cell: PhantomData<C>,
}
#[derive(Debug)]
pub struct RowRefMut<'t, 'tb> {
row: &'t mut Row<'tb>,
columns: &'t ColumnMap,
}
impl<'b> Row<'b> {
pub fn new(id: usize, cells: Vec<Cell<'b>>) -> Self {
Self { id, cells }
}
pub fn id(&self) -> usize {
self.id
}
pub fn into_cells(self) -> impl Iterator<Item = Cell<'b>> {
self.cells.into_iter()
}
pub fn cells(&self) -> impl Iterator<Item = &Cell<'b>> {
self.cells.iter()
}
pub fn id_hash(&self) -> Option<u32> {
self.cells.iter().find_map(|cell| match cell {
Cell::Single(Value::HashRef(id)) => Some(*id),
_ => None,
})
}
}
impl<'t, 'tb, C> RowRef<'t, 'tb, C>
where
C: FromCell<'t, 'tb>,
{
pub(crate) fn new(row: &'t Row<'tb>, columns: &'t ColumnMap) -> Self {
Self {
row,
columns,
_cell: PhantomData,
}
}
pub fn get_if_present(&self, column: impl Borrow<Label>) -> Option<C> {
let index = self.columns.position(column.borrow())?;
self.row.cells.get(index).map(C::from_cell)
}
pub fn get(&self, column: impl Borrow<Label>) -> C {
self.get_if_present(column).expect("no such column")
}
pub(crate) fn up_cast(self) -> RowRef<'t, 'tb> {
RowRef {
row: self.row,
columns: self.columns,
_cell: PhantomData,
}
}
}
impl<'t, 'tb> RowRef<'t, 'tb> {
pub(crate) fn down_cast<C>(self) -> RowRef<'t, 'tb, C> {
RowRef {
row: self.row,
columns: self.columns,
_cell: PhantomData,
}
}
}
impl<'a, 't: 'a, 'tb> RowRefMut<'t, 'tb> {
pub(crate) fn new(row: &'t mut Row<'tb>, columns: &'t ColumnMap) -> Self {
Self { row, columns }
}
pub fn get(&'t self, column: &'a Label) -> Option<&'t Cell<'tb>> {
let index = self.columns.position(column)?;
self.row.cells.get(index)
}
}
#[allow(useless_deprecated)]
#[deprecated(
since = "0.4.0",
note = "for removal in 0.5.0. The Index trait can't return owned types (required for specialized cells)"
)]
impl<'a, 't: 'a, 'tb, S> Index<S> for RowRef<'t, 'tb>
where
S: Into<Label> + PartialEq,
{
type Output = Cell<'tb>;
fn index(&self, index: S) -> &Self::Output {
self.get(&index.into())
}
}
impl<'t, 'tb, C> Deref for RowRef<'t, 'tb, C> {
type Target = Row<'tb>;
fn deref(&self) -> &Self::Target {
self.row
}
}
impl<'t, 'tb> Deref for RowRefMut<'t, 'tb> {
type Target = Row<'tb>;
fn deref(&self) -> &Self::Target {
self.row
}
}
impl<'t, 'tb> DerefMut for RowRefMut<'t, 'tb> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.row
}
}