use serde::Serialize;
use super::{Report, Severity};
pub(crate) fn render<W: std::io::Write>(
w: &mut W,
report: &Report,
json: bool,
strict: bool,
) -> std::io::Result<()> {
if json {
render_json(w, report, strict)
} else {
render_human(w, report)
}
}
const fn symbol(sev: Severity) -> char {
match sev {
Severity::Pass => '\u{2714}', Severity::Warn => '\u{26a0}', Severity::Fail => '\u{2716}', }
}
fn render_human<W: std::io::Write>(w: &mut W, report: &Report) -> std::io::Result<()> {
writeln!(w, "decdn node doctor")?;
let mut current: Option<&str> = None;
for finding in &report.findings {
if current != Some(finding.group) {
writeln!(w, "\n{}", finding.group)?;
current = Some(finding.group);
}
writeln!(w, " {} {}", symbol(finding.severity), finding.title)?;
if let Some(detail) = &finding.detail {
writeln!(w, " {detail}")?;
}
if let Some(rem) = &finding.remediation {
writeln!(w, " fix: {rem}")?;
}
}
let (p, warn, f) = report.counts();
writeln!(w, "\nSummary: {p} passed, {warn} warnings, {f} failed")
}
#[derive(Serialize)]
struct JsonReport<'a> {
findings: &'a [super::Finding],
summary: JsonSummary,
ok: bool,
}
#[derive(Serialize)]
struct JsonSummary {
pass: usize,
warn: usize,
fail: usize,
}
fn render_json<W: std::io::Write>(w: &mut W, report: &Report, strict: bool) -> std::io::Result<()> {
let (pass, warn, fail) = report.counts();
let doc = JsonReport {
findings: &report.findings,
summary: JsonSummary { pass, warn, fail },
ok: fail == 0 && !(strict && warn > 0),
};
let text = serde_json::to_string_pretty(&doc).map_err(std::io::Error::other)?;
writeln!(w, "{text}")
}
#[cfg(test)]
#[allow(
clippy::unwrap_used,
clippy::expect_used,
clippy::panic,
clippy::indexing_slicing
)] mod tests;