use ciborium::Value as CborValue;
use vantage_core::{Result, error};
use vantage_table::column::flags::ColumnFlag;
use vantage_table::table::Table;
use vantage_table::traits::column_like::ColumnLike;
use vantage_types::{EmptyEntity, Entity};
use vantage_vista::{
Column as VistaColumn, NoExtras, Vista, VistaCapabilities, VistaFactory, VistaMetadata,
flags as vista_flags,
};
use crate::AwsAccount;
use crate::vista::source::AwsTableShell;
use crate::vista::spec::{AwsColumnExtras, AwsTableExtras, AwsVistaSpec};
pub struct AwsVistaFactory {
aws: AwsAccount,
}
impl AwsVistaFactory {
pub fn new(aws: AwsAccount) -> Self {
Self { aws }
}
pub fn from_table<E>(&self, table: Table<AwsAccount, E>) -> Result<Vista>
where
E: Entity<CborValue> + 'static,
{
let name = table.table_name().to_string();
let any_table = table.into_entity::<EmptyEntity>();
Ok(self.wrap(any_table, name))
}
fn wrap(&self, table: Table<AwsAccount, EmptyEntity>, name: String) -> Vista {
let metadata = metadata_from_table(&table);
let source = AwsTableShell::new(
table,
VistaCapabilities {
can_count: true,
..VistaCapabilities::default()
},
metadata,
);
Vista::new(name, Box::new(source))
}
pub fn aws(&self) -> &AwsAccount {
&self.aws
}
}
impl VistaFactory for AwsVistaFactory {
type TableExtras = AwsTableExtras;
type ColumnExtras = AwsColumnExtras;
type ReferenceExtras = NoExtras;
fn build_from_spec(&self, _spec: AwsVistaSpec) -> Result<Vista> {
Err(error!(
"AWS Vista YAML spec construction is not implemented — \
build a typed table via the constructors in `vantage_aws::models` \
and wrap it with `AwsVistaFactory::from_table`"
))
}
}
pub(crate) fn metadata_from_table<E>(table: &Table<AwsAccount, E>) -> VistaMetadata
where
E: Entity<CborValue> + 'static,
{
let mut metadata = VistaMetadata::new();
for (name, col) in table.columns() {
let mut vc = VistaColumn::new(name.clone(), col.get_type().to_string());
if col.flags().contains(&ColumnFlag::Hidden) {
vc = vc.with_flag(vista_flags::HIDDEN);
}
metadata = metadata.with_column(vc);
}
if let Some(id_field) = table.id_field() {
let id_name = id_field.name().to_string();
metadata = metadata.with_id_column(id_name.clone());
if let Some(col) = metadata.columns.get_mut(&id_name) {
col.flags.push(vista_flags::ID.to_string());
}
}
for title in table.title_fields() {
if let Some(col) = metadata.columns.get_mut(title) {
col.flags.push(vista_flags::TITLE.to_string());
}
}
metadata
}