use comfy_table::{Attribute, Cell, Color, Table as ComfyTable};
use indexmap::IndexMap;
use vantage_dataset::prelude::ReadableValueSet;
use vantage_table::prelude::ColumnLike;
use vantage_table::table::Table;
use vantage_table::traits::table_source::TableSource;
use vantage_types::{Entity, Record, TerminalRender};
fn hint_to_color(hint: &str) -> Option<Color> {
match hint {
"green" => Some(Color::Green),
"red" => Some(Color::Red),
"blue" => Some(Color::Blue),
"yellow" => Some(Color::Yellow),
"cyan" => Some(Color::Cyan),
"magenta" => Some(Color::Magenta),
_ => None,
}
}
fn render_cell<V: TerminalRender>(value: &V) -> Cell {
let text = value.render();
let mut cell = Cell::new(&text);
if let Some(hint) = value.color_hint() {
if hint == "dim" {
cell = cell.add_attribute(Attribute::Dim);
} else if let Some(color) = hint_to_color(hint) {
cell = cell.fg(color);
}
}
cell
}
pub async fn print_table<T, E>(table: &Table<T, E>) -> vantage_core::Result<()>
where
T: TableSource,
T::Value: TerminalRender,
T::Id: std::fmt::Display,
E: Entity<T::Value>,
{
let id_field = table.id_field().map(|col| col.name().to_string());
let records = table.list_values().await?;
render_records(&records, id_field.as_deref());
Ok(())
}
pub fn render_records<Id: std::fmt::Display, V: TerminalRender>(
records: &IndexMap<Id, Record<V>>,
id_field: Option<&str>,
) {
if records.is_empty() {
println!("No records found.");
return;
}
let first_record = records.values().next().unwrap();
let columns: Vec<&String> = first_record
.keys()
.filter(|k| k.as_str() != "id" && Some(k.as_str()) != id_field)
.collect();
let mut table = ComfyTable::new();
let mut header = vec![Cell::new("id").add_attribute(Attribute::Bold)];
header.extend(
columns
.iter()
.map(|c| Cell::new(c).add_attribute(Attribute::Bold)),
);
table.set_header(header);
for (id, record) in records {
let mut row = vec![Cell::new(id)];
for col in &columns {
if let Some(value) = record.get(col.as_str()) {
row.push(render_cell(value));
} else {
row.push(Cell::new(""));
}
}
table.add_row(row);
}
println!("{table}");
println!("Found {} records", records.len());
}