Skip to main content

siderite_cli/report/
text.rs

1//! Text renderers. They reproduce the historical terminal output of
2//! `check` and `routes` byte for byte.
3
4use super::{CheckSummary, Diagnostic, Envelope, RouteReport, redact_text};
5
6/// One line of a diagnostic: `error: [models.E003] message`. The
7/// message is redacted again, whatever produced the diagnostic.
8pub fn diagnostic_line(d: &Diagnostic) -> String {
9    format!(
10        "{}: [{}] {}",
11        d.severity().as_str(),
12        d.code(),
13        redact_text(d.message())
14    )
15}
16
17/// Render a `check` report: one line per diagnostic, then a summary line.
18pub fn render_check(report: &Envelope<CheckSummary>) -> String {
19    let mut out = String::new();
20    for d in &report.diagnostics {
21        out.push_str(&diagnostic_line(d));
22        out.push('\n');
23    }
24    if report.diagnostics.is_empty() {
25        out.push_str("System check identified no issues.\n");
26    } else {
27        out.push_str(&format!(
28            "System check identified {} issue(s).\n",
29            report.diagnostics.len()
30        ));
31    }
32    out
33}
34
35/// Render routes as an aligned table, one route per line.
36pub fn render_routes(routes: &[RouteReport]) -> String {
37    render_route_rows(routes.iter().map(|r| {
38        (
39            r.method.as_str(),
40            r.path.as_str(),
41            r.operation_id.as_deref(),
42        )
43    }))
44}
45
46/// The table behind [`render_routes`], over `(method, path, id)` rows.
47pub(crate) fn render_route_rows<'a>(
48    rows: impl Iterator<Item = (&'a str, &'a str, Option<&'a str>)> + Clone,
49) -> String {
50    let method_width = rows.clone().map(|r| r.0.len()).max().unwrap_or(0);
51    let path_width = rows.clone().map(|r| r.1.len()).max().unwrap_or(0);
52    let mut out = String::new();
53    for (method, path, id) in rows {
54        let id = id.unwrap_or("-");
55        out.push_str(&format!(
56            "{method:<method_width$}  {path:<path_width$}  {id}\n"
57        ));
58    }
59    if out.is_empty() {
60        return "No routes.\n".to_owned();
61    }
62    out
63}