use std::io::Write;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Change {
Unchanged,
Create,
Update,
Remove,
}
impl Change {
fn label(self, dry_run: bool) -> &'static str {
match (self, dry_run) {
(Change::Unchanged, _) => "unchanged",
(Change::Create, false) => "created",
(Change::Update, false) => "updated",
(Change::Remove, false) => "removed",
(Change::Create, true) => "would create",
(Change::Update, true) => "would update",
(Change::Remove, true) => "would remove",
}
}
}
pub struct Report<'w> {
out: &'w mut dyn Write,
dry_run: bool,
changes: usize,
}
impl<'w> Report<'w> {
pub fn new(out: &'w mut dyn Write, dry_run: bool) -> Self {
Report {
out,
dry_run,
changes: 0,
}
}
pub fn dry_run(&self) -> bool {
self.dry_run
}
pub fn changes(&self) -> usize {
self.changes
}
pub fn line(&mut self, text: impl AsRef<str>) {
let _ = writeln!(self.out, "{}", text.as_ref());
}
pub fn step(&mut self, id: &str, subject: &str, change: Change, preview: Option<&str>) {
if change != Change::Unchanged {
self.changes += 1;
}
self.line(format!(
" [{:<12}] {id:<36} {subject}",
change.label(self.dry_run)
));
if self.dry_run
&& change != Change::Unchanged
&& let Some(p) = preview
{
for l in p.lines() {
self.line(format!(" | {l}"));
}
}
}
}