Skip to main content

callisto_cli/
output.rs

1use std::io;
2
3use serde::Serialize;
4
5use crate::cli::OutputFormat;
6
7pub fn write_json<W: io::Write, S: Serialize + ?Sized>(w: &mut W, val: &S) -> io::Result<()> {
8    let text = serde_json::to_string_pretty(val)?;
9    writeln!(w, "{text}")
10}
11
12/// Serializes a `Report` value to JSON, injecting a `"command"` discriminator
13/// field so consumers can distinguish report types (e.g. `"plan-publish"` vs
14/// `"publish"`) without inspecting payload structure.
15pub fn write_report_json<W: io::Write, R: callisto_model::Report>(w: &mut W, val: &R) -> io::Result<()> {
16    #[derive(Serialize)]
17    struct WithCommand<'a, T: Serialize> {
18        command: &'static str,
19        #[serde(flatten)]
20        data: &'a T,
21    }
22    let tagged = WithCommand {
23        command: R::COMMAND,
24        data: val,
25    };
26    let text = serde_json::to_string_pretty(&tagged)?;
27    writeln!(w, "{text}")
28}
29
30pub fn log_line(format: OutputFormat, line: &str) {
31    match format {
32        OutputFormat::Json => eprintln!("{line}"),
33        OutputFormat::Text => println!("{line}"),
34    }
35}
36
37/// Trait implemented by CLI report structures to guarantee clean JSON stream splitting and diagnostic card formatting.
38pub trait ReportPresenter: Serialize {
39    fn present_json<W: io::Write>(&self, w: &mut W) -> io::Result<()> {
40        write_json(w, self)
41    }
42
43    fn present_human(&self) -> String;
44}