1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
//! Structured-event channel for command output.
//!
//! Every command emits through the [`Output`] trait. The renderer chosen by
//! `--output` decides formatting: [`TerminalRenderer`] for human-readable,
//! column-aligned text with optional ANSI color, or [`JsonOutput`] for
//! newline-delimited JSON. Both write to stdout.
//!
//! This is distinct from `log::*!`. `log::*!` is the runtime-event channel
//! (debug breadcrumbs, gated behind `RUST_LOG`); the [`Output`] trait is the
//! structured-output channel (the actual command result). They don't bridge.
//! The stdout/stderr split — `Output` to stdout, `log::*!` and fatal errors
//! to stderr — keeps `--output json` parseable even with `RUST_LOG=debug`.
//!
//! Each command uses a subset of the trait surface: `apply` and `status`
//! emit [`Status`] and [`AppliedAction`]; `pkg` emits [`PkgEntry`]; `doctor`
//! emits [`DoctorCheck`]; `init` (without `--apply`) emits [`InitSummary`].
//! The trait is intentionally polymorphic — multiple impls (and shapes like
//! `JsonSchema` derives on the event types) are part of the contract; don't
//! collapse it into a concrete formatter.
use JsonSchema;
use Serialize;
pub use ;
pub use JsonOutput;
pub use TerminalRenderer;
/// Errors surfaced by [`Output`] implementations. `Io` comes from
/// `writeln!` / `write!` on the backing `Write`; `Json` from
/// `serde_json::to_writer` in `JsonOutput`. Both variants use
/// `#[error(transparent)]` so the user sees the underlying message
/// verbatim.
/// One structured output event. The renderer match-dispatches; the JSON
/// renderer serialises this directly with the `event` tag (e.g. `{"event":
/// "status", ...}`).
/// The structured-output channel a command emits through. See the
/// [module-level docs](self) for how this relates to `log::*!` and how the
/// renderer is chosen.
///
/// One method, [`push`](Output::push), takes any [`Event`] variant; the
/// renderer match-dispatches internally. [`finalize`](Output::finalize) is
/// called once at the end of a command — `JsonOutput` streams as it goes
/// and treats it as a no-op; `TerminalRenderer` accumulates rows so it can
/// column-align them and flushes here.