//! Output format abstraction for JSON and human-readable rendering. //! //! Every command result type implements [`HumanReadable`] so the CLI can //! switch between `--json` (machine-readable) and the default tabular output //! with a single [`render`] call. use serde::Serialize; use std::io::Write; /// Output format selected by the global `--json` flag. #[derive(Debug, Clone, Copy)] pub enum OutputFormat { /// Default: pretty-printed tables/text for humans. Human, /// Structured JSON (for CI pipelines, LLM tool-use, jq). Json, } /// Render any serializable result in the chosen format. /// /// # Errors /// /// Returns an error if JSON serialization or stdout writing fails. pub fn render(result: &T, format: OutputFormat) -> anyhow::Result<()> { match format { OutputFormat::Json => { let json = serde_json::to_string_pretty(result)?; let mut stdout = std::io::stdout().lock(); writeln!(stdout, "{json}")?; } OutputFormat::Human => { result.print_human(); } } Ok(()) } /// Trait for human-readable terminal rendering. /// /// Implementors print directly to stdout using `println!`, `colored`, or /// `tabled` — whatever looks best for the data type. pub trait HumanReadable { /// Print a human-friendly representation to stdout. fn print_human(&self); }