use indexmap::IndexMap;
use crate::{
column::{Column, ColumnFlag},
reference::Reference,
};
#[derive(Debug, Clone, Default)]
#[non_exhaustive]
pub struct VistaMetadata {
pub columns: IndexMap<String, Column>,
pub references: IndexMap<String, Reference>,
pub id_column: Option<String>,
}
impl VistaMetadata {
pub fn new() -> Self {
Self::default()
}
pub fn with_column(mut self, column: Column) -> Self {
self.columns.insert(column.name.clone(), column);
self
}
pub(crate) fn with_column_at(mut self, index: usize, column: Column) -> Self {
let index = index.min(self.columns.len());
self.columns
.shift_insert(index, column.name.clone(), column);
self
}
pub fn with_columns_at<'a>(
self,
columns: impl IntoIterator<Item = (usize, &'a Column)>,
) -> Self {
columns.into_iter().fold(self, |metadata, (at, column)| {
metadata.with_column_at(at, column.clone())
})
}
pub fn with_reference(mut self, reference: Reference) -> Self {
self.references.insert(reference.name.clone(), reference);
self
}
pub fn with_id_column(mut self, name: impl Into<String>) -> Self {
self.id_column = Some(name.into());
self
}
pub fn search_columns(&self) -> Vec<&str> {
let flagged: Vec<&str> = self
.columns
.values()
.filter(|column| column.has_flag(ColumnFlag::Searchable))
.map(|column| column.name.as_str())
.collect();
if flagged.is_empty() {
self.columns.keys().map(String::as_str).collect()
} else {
flagged
}
}
}