1use std::io::{self, Write};
5
6use crate::error::Error;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9pub enum Format {
10 Human,
11 Json,
12}
13
14#[derive(Debug, Clone, Copy)]
15pub struct Output {
16 pub format: Format,
17}
18
19impl Output {
20 pub fn new(json: bool) -> Self {
21 Self {
22 format: if json { Format::Json } else { Format::Human },
23 }
24 }
25
26 pub fn is_json(&self) -> bool {
27 self.format == Format::Json
28 }
29
30 pub fn json(&self, value: &serde_json::Value) {
32 if self.is_json()
33 && let Ok(s) = serde_json::to_string_pretty(value)
34 {
35 println!("{s}");
36 }
37 }
38
39 pub fn line(&self, text: impl AsRef<str>) {
41 if !self.is_json() {
42 println!("{}", text.as_ref());
43 }
44 }
45
46 pub fn warn(&self, text: impl AsRef<str>) {
48 let _ = writeln!(io::stderr(), "{}", text.as_ref());
49 }
50
51 pub fn emit_error(&self, err: &Error) -> i32 {
53 match self.format {
54 Format::Json => {
55 if let Ok(s) = serde_json::to_string_pretty(&err.to_json()) {
56 let _ = writeln!(io::stderr(), "{s}");
57 }
58 }
59 Format::Human => {
60 let _ = writeln!(
61 io::stderr(),
62 "error ({}): {}",
63 err.kind.as_str(),
64 err.message
65 );
66 }
67 }
68 err.exit_code()
69 }
70}