use comfy_table::{Cell, Table};
use crate::sources::resolve::ResolvedSource;
use crate::sources::{VersionedSource, print_errors};
use crate::{Results, error::ErrorWithData};
fn new_table(header: Vec<&str>) -> Table {
use comfy_table::{ColumnConstraint, ContentArrangement, Width, presets::UTF8_FULL};
let mut table = Table::new();
table
.load_style(UTF8_FULL)
.set_content_arrangement(ContentArrangement::DynamicFullWidth)
.set_width(100)
.set_header(header);
if let Some(column) = table.column_mut(0) {
column.set_constraint(ColumnConstraint::UpperBoundary(Width::Fixed(30)));
}
table
}
pub(crate) fn display_results<F>(
results: Results<ResolvedSource, ErrorWithData<VersionedSource>>,
columns: &[&str],
row: F,
) where
F: Fn(&ResolvedSource) -> Vec<Cell>,
{
use itertools::Itertools;
let (sources, errors) = results.split();
let groups = sources
.into_iter()
.into_group_map_by(|source| source.source.source.to_string())
.into_iter()
.sorted_unstable_by_key(|(kind, _)| kind.clone());
for (kind, mut sources) in groups {
let mut header = vec![kind.as_str()];
header.extend_from_slice(columns);
let mut table = new_table(header);
sources.sort_by_key(|source| std::cmp::Reverse(source.wanted.is_some()));
for source in &sources {
table.add_row(row(source));
}
println!("{table}");
}
print_errors(errors);
}
pub(crate) fn common_cells(source: &ResolvedSource) -> Vec<Cell> {
let current = source.source.current.as_deref().unwrap_or("N/A");
let wanted = source
.wanted
.as_deref()
.map_or_else(|| "N/A".to_owned(), ToOwned::to_owned);
vec![
Cell::new(source.source.source.describe()),
Cell::new(current),
Cell::new(wanted),
Cell::new(source.latest.clone()),
Cell::new(
source
.source
.source
.location()
.map_or_else(|| "-".to_owned(), ToString::to_string),
),
]
}