use ciborium::Value as CborValue;
use vantage_core::Result;
use vantage_table::column::flags::ColumnFlag;
use vantage_table::table::Table;
use vantage_table::traits::column_like::ColumnLike;
use vantage_types::Entity;
use vantage_vista::{
Column as VistaColumn, Reference as VistaReference, ReferenceKind, Vista, VistaCapabilities,
VistaFactory, VistaMetadata, flags as vista_flags,
};
use crate::RestApi;
use crate::vista::source::RestApiTableShell;
use crate::vista::spec::{NoApiExtras, RestApiVistaSpec};
pub struct RestApiVistaFactory {
api: RestApi,
}
impl RestApiVistaFactory {
pub fn new(api: RestApi) -> Self {
Self { api }
}
pub fn api(&self) -> &RestApi {
&self.api
}
pub fn from_table<E>(&self, table: Table<RestApi, E>) -> Result<Vista>
where
E: Entity<CborValue> + 'static,
{
let metadata = metadata_from_table(&table);
let name = table.table_name().to_string();
let source = RestApiTableShell::new(
Box::new(table),
VistaCapabilities {
can_count: true,
..VistaCapabilities::default()
},
);
Ok(Vista::new(name, Box::new(source), metadata))
}
}
impl VistaFactory for RestApiVistaFactory {
type TableExtras = NoApiExtras;
type ColumnExtras = NoApiExtras;
type ReferenceExtras = NoApiExtras;
fn build_from_spec(&self, _spec: RestApiVistaSpec) -> Result<Vista> {
Err(vantage_core::error!(
"YAML spec construction not yet implemented for RestApiVistaFactory"
))
}
}
fn metadata_from_table<E>(table: &Table<RestApi, 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 = id_field.name().to_string();
metadata = metadata.with_id_column(id.clone());
if let Some(col) = metadata.columns.get_mut(&id) {
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());
}
}
for relation in table.references() {
metadata = metadata.with_reference(VistaReference::new(
relation.clone(),
"",
ReferenceKind::HasMany,
"",
));
}
metadata
}