use crate::models::{Cell, Column, Row};
use core::option::Option;
use std::collections::HashMap;
type ColumnNameToId<'a> = HashMap<&'a str, u64>;
type ColumnIdToName<'a> = HashMap<u64, &'a str>;
pub struct ColumnMapper<'a> {
pub name_to_id: ColumnNameToId<'a>,
pub id_to_name: ColumnIdToName<'a>,
}
impl<'a> ColumnMapper<'a> {
pub fn new(columns: &'a Vec<Column>) -> Self {
let (name_to_id, id_to_name) = Self::get_mappings(columns);
Self {
name_to_id,
id_to_name,
}
}
fn get_mappings(columns: &'a Vec<Column>) -> (ColumnNameToId, ColumnIdToName) {
let num_columns = columns.len();
if num_columns == 0 {
panic!("No column data for the Row - please ensure you call `get_row_with_column_data()` *or* \
pass `RowIncludeFlags::Columns` as an `include` argument to `get_row_with_params()`")
}
let mut name_to_id: ColumnNameToId<'a> = HashMap::with_capacity(num_columns);
let mut id_to_name: ColumnIdToName<'a> = HashMap::with_capacity(num_columns);
for c in columns {
let title = &c.title;
name_to_id.insert(title, c.id);
id_to_name.insert(c.id, title);
}
(name_to_id, id_to_name)
}
}
pub struct CellGetter<'a> {
column_name_to_id: &'a ColumnNameToId<'a>,
}
impl<'a> CellGetter<'a> {
pub fn from_mapper(columns: &'a ColumnMapper<'a>) -> Self {
Self {
column_name_to_id: &columns.name_to_id,
}
}
pub fn from_name_to_id(column_name_to_id: &'a ColumnNameToId<'a>) -> Self {
Self { column_name_to_id }
}
pub fn by_name<'b>(&'a self, row: &'a Row, name: &'b str) -> Option<&Cell> {
if let Some(&col_id) = self.column_name_to_id.get(name) {
row.get_cell_by_id(col_id)
} else {
None
}
}
pub fn by_id(&'a self, row: &'a Row, column_id: u64) -> Option<&Cell> {
row.get_cell_by_id(column_id)
}
}