use std::fmt::Write as _;
use crate::api::{BulkChange, BulkOutcome};
use crate::render::Context;
use crate::render::style::Palette;
use crate::render::table::{Column, render};
#[must_use]
pub fn changed(done: u64, total: u64, ctx: &Context) -> String {
let colour = if done == total {
Palette::label()
} else {
Palette::warn()
};
format!(
"{}\n",
ctx.painter()
.paint(&format!("changed {done} of {total}"), colour)
)
}
#[must_use]
pub fn change(change: &BulkChange, ctx: &Context) -> String {
let paint = ctx.painter();
let mut out = String::with_capacity(96);
let counted = match (change.done, change.total) {
(Some(done), Some(total)) => format!("changed {done} of {total}"),
_ => format!("{} — not counted yet", change.status.to_lowercase()),
};
let colour = if change.succeeded() {
Palette::label()
} else {
Palette::warn()
};
let _ = writeln!(
out,
"{} {}",
paint.paint(&counted, colour),
paint.paint(&format!("bulkchange {}", change.id), Palette::key())
);
if !change.succeeded() && !change.status_text.is_empty() {
let _ = writeln!(out, "{}", paint.paint(&change.status_text, Palette::warn()));
}
out
}
#[must_use]
pub fn failures(outcomes: &[BulkOutcome], ctx: &Context) -> String {
let rows: Vec<Vec<String>> = outcomes
.iter()
.filter(|outcome| outcome.status != "COMPLETE")
.map(|outcome| {
vec![
outcome.key.clone(),
outcome.status.to_lowercase(),
outcome.error.clone().unwrap_or_else(|| "-".to_owned()),
]
})
.collect();
if rows.is_empty() {
return String::new();
}
render(
&[
Column::whole("KEY", 14, Palette::key()),
Column::whole("STATUS", 10, Palette::warn()),
Column::new("WHY", 48, anstyle::Style::new()),
],
&rows,
ctx,
)
}