use crate::error::MattenDataError;
use crate::table::{CellValue, Table};
#[derive(Debug, Clone)]
pub struct NumericTable {
headers: Vec<String>,
data: Vec<f64>,
rows: usize,
cols: usize,
}
impl NumericTable {
pub fn row_count(&self) -> usize {
self.rows
}
pub fn column_count(&self) -> usize {
self.cols
}
pub fn column_names(&self) -> &[String] {
&self.headers
}
pub fn to_tensor(&self) -> Result<matten::Tensor, MattenDataError> {
if self.cols == 0 {
return Err(MattenDataError::EmptySelection);
}
matten::Tensor::try_new(self.data.clone(), &[self.rows, self.cols])
.map_err(MattenDataError::Matten)
}
}
pub(crate) fn try_numeric(table: &Table) -> Result<NumericTable, MattenDataError> {
let headers: Vec<String> = table.headers().to_vec();
let cols = headers.len();
let table_rows = table.rows();
let rows = table_rows.len();
let mut data = Vec::with_capacity(rows * cols);
for (r, row) in table_rows.iter().enumerate() {
let line = r + 2;
for (c, cell) in row.iter().enumerate() {
let value = match cell {
CellValue::Int(i) => *i as f64,
CellValue::Float(f) => *f,
CellValue::Missing => {
return Err(MattenDataError::MissingValue {
column: headers[c].clone(),
row: line,
});
}
CellValue::Bool(b) => {
return Err(MattenDataError::NonNumericValue {
column: headers[c].clone(),
row: line,
value: b.to_string(),
});
}
CellValue::Text(s) => {
return Err(MattenDataError::NonNumericValue {
column: headers[c].clone(),
row: line,
value: s.clone(),
});
}
};
data.push(value);
}
}
Ok(NumericTable {
headers,
data,
rows,
cols,
})
}