use std::ops::Index;
use std::sync::Arc;
use crate::row::{Column, Row};
#[derive(Debug, Clone, PartialEq)]
pub struct DataTable {
name: String,
columns: Arc<[Column]>,
rows: Vec<Row>,
}
impl DataTable {
pub fn new(name: impl Into<String>, columns: Arc<[Column]>) -> Self {
Self {
name: name.into(),
columns,
rows: Vec::new(),
}
}
pub fn name(&self) -> &str {
&self.name
}
pub fn columns(&self) -> &[Column] {
&self.columns
}
pub fn rows(&self) -> &[Row] {
&self.rows
}
pub fn len(&self) -> usize {
self.rows.len()
}
pub fn is_empty(&self) -> bool {
self.rows.is_empty()
}
pub fn into_rows(self) -> Vec<Row> {
self.rows
}
pub(crate) fn push(&mut self, row: Row) {
self.rows.push(row);
}
}
impl Index<usize> for DataTable {
type Output = Row;
fn index(&self, index: usize) -> &Self::Output {
&self.rows[index]
}
}
#[derive(Debug, Clone, PartialEq, Default)]
pub struct DataSet {
tables: Vec<DataTable>,
}
impl DataSet {
pub fn new() -> Self {
Self::default()
}
pub fn tables(&self) -> &[DataTable] {
&self.tables
}
pub fn table(&self, index: usize) -> Option<&DataTable> {
self.tables.get(index)
}
pub fn table_named(&self, name: &str) -> Option<&DataTable> {
self.tables.iter().find(|t| t.name() == name)
}
pub fn len(&self) -> usize {
self.tables.len()
}
pub fn is_empty(&self) -> bool {
self.tables.is_empty()
}
pub fn into_rows(self) -> Vec<Row> {
self.tables
.into_iter()
.next()
.map(DataTable::into_rows)
.unwrap_or_default()
}
pub fn into_tables(self) -> Vec<DataTable> {
self.tables
}
pub(crate) fn push(&mut self, table: DataTable) {
self.tables.push(table);
}
}
impl Index<usize> for DataSet {
type Output = DataTable;
fn index(&self, index: usize) -> &Self::Output {
&self.tables[index]
}
}
#[cfg(test)]
mod tests;