rtb_tui/render.rs
1//! `render_table` / `render_json` — uniform structured-output
2//! helpers consumed by the v0.4 `--output text|json` flag.
3
4use serde::Serialize;
5use tabled::settings::Style;
6use tabled::{Table, Tabled};
7
8use crate::error::RenderError;
9
10/// Render `rows` as a `tabled` text table with the canonical v0.1
11/// style. Returns the rendered string with a trailing newline so
12/// callers can `print!` directly.
13///
14/// The style is fixed (`Style::psql()`) and there is no theming
15/// parameter; item W2 of [spec 0020] records why.
16///
17/// [spec 0020]: https://gitlab.com/phpboyscout/rust-tool-base/-/wikis/specs/0020-rtb-tui-v0.1
18#[must_use]
19pub fn render_table<R: Tabled>(rows: &[R]) -> String {
20 let mut table = Table::new(rows);
21 table.with(Style::psql());
22 let mut s = table.to_string();
23 if !s.ends_with('\n') {
24 s.push('\n');
25 }
26 s
27}
28
29/// Render `rows` as a pretty-printed JSON array (one element per
30/// row, two-space indent, trailing newline).
31///
32/// # Errors
33///
34/// [`RenderError::Json`] when any row fails to serialise: a map key
35/// that is not string-like (a tuple, say), or a `Serialize` impl that
36/// returns an error. Non-finite floats serialise as `null` and integer
37/// keys are stringified, so neither fails. The payload is a
38/// stringified `serde_json::Error`.
39pub fn render_json<R: Serialize>(rows: &[R]) -> Result<String, RenderError> {
40 let mut out =
41 serde_json::to_string_pretty(rows).map_err(|e| RenderError::Json(e.to_string()))?;
42 out.push('\n');
43 Ok(out)
44}