use crate::{
BdatVersion, ColumnDef, ColumnMap, Label, LegacyCell, ModernTable, Row, RowRef, RowRefMut,
Table, TableAccessor, TableBuilder,
};
use super::{FormatConvertError, TableInner};
#[derive(Debug, Clone, PartialEq)]
pub struct LegacyTable<'b> {
pub(crate) name: Label,
pub(crate) base_id: usize,
pub(crate) columns: ColumnMap,
pub(crate) rows: Vec<Row<'b>>,
}
impl<'b> LegacyTable<'b> {
pub(crate) fn new(builder: TableBuilder<'b>) -> Self {
Self {
name: builder.name,
columns: builder.columns,
base_id: builder
.rows
.iter()
.map(|r| r.id())
.min()
.unwrap_or_default(),
rows: builder.rows,
}
}
pub fn rows(&self) -> impl Iterator<Item = RowRef<'_, 'b, LegacyCell<'_, 'b>>> {
self.rows.iter().map(|row| RowRef::new(row, &self.columns))
}
pub fn rows_mut(&mut self) -> impl Iterator<Item = RowRefMut<'_, 'b>> {
self.rows
.iter_mut()
.map(|row| RowRefMut::new(row, &self.columns))
}
pub fn into_rows(self) -> impl Iterator<Item = Row<'b>> {
self.rows.into_iter()
}
pub fn columns(&self) -> impl Iterator<Item = &ColumnDef> {
self.columns.as_slice().iter()
}
pub fn columns_mut(&mut self) -> impl Iterator<Item = &mut ColumnDef> {
self.columns.as_mut_slice().iter_mut()
}
pub fn into_columns(self) -> impl Iterator<Item = ColumnDef> {
self.columns.into_raw().into_iter()
}
}
impl<'t, 'b: 't> TableAccessor<'t, 'b> for LegacyTable<'b> {
type Cell = LegacyCell<'t, 'b>;
fn name(&self) -> &Label {
&self.name
}
fn set_name(&mut self, name: Label) {
self.name = name;
}
fn base_id(&self) -> usize {
self.base_id
}
fn get_row(&self, id: usize) -> Option<RowRef<'_, 'b, LegacyCell<'_, 'b>>> {
let index = id.checked_sub(self.base_id)?;
self.rows
.get(index)
.map(|row| RowRef::new(row, &self.columns))
}
fn get_row_mut(&mut self, id: usize) -> Option<RowRefMut<'_, 'b>> {
let index = id.checked_sub(self.base_id)?;
self.rows
.get_mut(index)
.map(|row| RowRefMut::new(row, &self.columns))
}
fn row_count(&self) -> usize {
self.rows.len()
}
fn column_count(&self) -> usize {
self.columns.as_slice().len()
}
}
impl<'b> From<LegacyTable<'b>> for TableBuilder<'b> {
fn from(value: LegacyTable<'b>) -> Self {
Self {
name: value.name,
columns: value.columns,
rows: value.rows,
}
}
}
impl<'b> From<LegacyTable<'b>> for Table<'b> {
fn from(value: LegacyTable<'b>) -> Self {
Self {
inner: TableInner::Legacy(value),
}
}
}
impl<'b> TryFrom<ModernTable<'b>> for LegacyTable<'b> {
type Error = FormatConvertError;
fn try_from(value: ModernTable<'b>) -> Result<Self, Self::Error> {
if let Some(col) = value
.columns()
.find(|c| !c.value_type().is_supported(BdatVersion::LegacySwitch))
{
return Err(FormatConvertError::UnsupportedValueType(col.value_type()));
}
Ok(LegacyTable::new(TableBuilder::from(value)))
}
}