use crate::{Cell, CellAccessor, ColumnMap, CompatTable, LegacyColumn, RowRef, Utf};
use super::{
builder::LegacyTableBuilder,
private::{ColumnSerialize, LabelMap, Table},
util::EnumId,
};
#[derive(Debug, Clone, PartialEq)]
pub struct LegacyTable<'b> {
pub(crate) name: Utf<'b>,
pub(crate) base_id: u16,
pub(crate) columns: ColumnMap<LegacyColumn<'b>, Utf<'b>>,
pub(crate) rows: Vec<LegacyRow<'b>>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct LegacyRow<'b> {
pub(crate) cells: Vec<Cell<'b>>,
}
pub type LegacyRowRef<'t, 'buf> = RowRef<&'t LegacyRow<'buf>, &'t ColumnMap<LegacyColumn<'buf>>>;
pub type LegacyRowMut<'t, 'buf> =
RowRef<&'t mut LegacyRow<'buf>, &'t ColumnMap<LegacyColumn<'buf>>>;
impl<'b> LegacyTable<'b> {
pub(crate) fn new(builder: LegacyTableBuilder<'b>) -> Self {
Self {
name: builder.name,
columns: builder.columns,
base_id: builder.base_id,
rows: builder.rows,
}
}
pub fn name(&self) -> &str {
&self.name
}
pub fn set_name(&mut self, name: Utf<'b>) {
self.name = name;
}
pub fn base_id(&self) -> u16 {
self.base_id
}
pub fn row(&self, id: u16) -> LegacyRowRef<'_, 'b> {
self.get_row(id).expect("row not found")
}
pub fn row_mut(&mut self, id: u16) -> LegacyRowMut<'_, 'b> {
self.get_row_mut(id).expect("row not found")
}
pub fn get_row(&self, id: u16) -> Option<LegacyRowRef<'_, 'b>> {
let index = id.checked_sub(self.base_id)?;
self.rows
.get(index as usize)
.map(|row| RowRef::new(id as u32, row, &self.columns))
}
pub fn get_row_mut(&mut self, id: u16) -> Option<LegacyRowMut<'_, 'b>> {
let index = id.checked_sub(self.base_id)?;
self.rows
.get_mut(index as usize)
.map(|row| RowRef::new(id as u32, row, &self.columns))
}
pub fn rows(&self) -> impl Iterator<Item = LegacyRowRef<'_, 'b>> {
self.rows
.iter()
.enum_id(self.base_id as u32)
.map(|(id, row)| RowRef::new(id, row, &self.columns))
}
pub fn rows_mut(&mut self) -> impl Iterator<Item = LegacyRowMut<'_, 'b>> {
self.rows
.iter_mut()
.enum_id(self.base_id as u32)
.map(|(id, row)| RowRef::new(id, row, &self.columns))
}
pub fn into_rows(self) -> impl Iterator<Item = LegacyRow<'b>> {
self.rows.into_iter()
}
pub fn into_rows_id(self) -> impl Iterator<Item = (u16, LegacyRow<'b>)> {
self.rows.into_iter().enum_id(self.base_id)
}
pub fn columns(&self) -> impl Iterator<Item = &LegacyColumn<'b>> {
self.columns.iter()
}
pub fn columns_mut(&mut self) -> impl Iterator<Item = &mut LegacyColumn<'b>> {
self.columns.as_mut_slice().iter_mut()
}
pub fn into_columns(self) -> impl Iterator<Item = LegacyColumn<'b>> {
self.columns.into_raw().into_iter()
}
pub fn row_count(&self) -> usize {
self.rows.len()
}
pub fn column_count(&self) -> usize {
self.columns.as_slice().len()
}
}
impl<'b> LegacyRow<'b> {
pub fn new(cells: Vec<Cell<'b>>) -> Self {
Self { cells }
}
pub fn cells(&self) -> impl Iterator<Item = &Cell<'b>> {
self.cells.iter()
}
pub fn into_cells(self) -> impl Iterator<Item = Cell<'b>> {
self.cells.into_iter()
}
}
impl<'buf> Table<'buf> for LegacyTable<'buf> {
type Id = u16;
type Name = Utf<'buf>;
type Row = LegacyRow<'buf>;
type BuilderRow = LegacyRow<'buf>;
type Column = LegacyColumn<'buf>;
type BuilderColumn = LegacyColumn<'buf>;
}
impl<'a, 'b> CellAccessor for &'a LegacyRow<'b> {
type Target = &'a Cell<'b>;
fn access(self, pos: usize) -> Option<Self::Target> {
self.cells.get(pos)
}
}
impl<'a, 'b> CellAccessor for &'a mut LegacyRow<'b> {
type Target = &'a mut Cell<'b>;
fn access(self, pos: usize) -> Option<Self::Target> {
self.cells.get_mut(pos)
}
}
impl<'b> From<LegacyTable<'b>> for LegacyTableBuilder<'b> {
fn from(value: LegacyTable<'b>) -> Self {
Self::from_table(value.name, value.base_id, value.columns, value.rows)
}
}
impl<'b> From<LegacyTable<'b>> for CompatTable<'b> {
fn from(value: LegacyTable<'b>) -> Self {
Self::Legacy(value)
}
}
impl<'t, 'b> LabelMap for &'t ColumnMap<LegacyColumn<'b>, Utf<'b>> {
type Name = Utf<'b>;
fn position(&self, label: &Self::Name) -> Option<usize> {
self.label_map.position(label)
}
}
impl<'buf> ColumnSerialize for LegacyColumn<'buf> {
fn ser_value_type(&self) -> crate::ValueType {
self.value_type()
}
fn ser_flags(&self) -> &[crate::LegacyFlag] {
&self.flags
}
}