Skip to main content

writer/
tool_io.rs

1// Copyright 2023 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use std::fmt::Display;
6use std::io::Write;
7
8use crate::{Error, Result};
9
10/// ToolIO defines the necessary functions to perform output from a tool,
11/// potentially including type-safe machine output if required.
12///
13/// There are three provided implementations:
14// [`crate::MachineWriter`] and [`crate::VerifiedMachineWriter`],
15/// and [`crate::SimpleWriter`]. These provide either type-safe,
16/// type-safe with schema, or string-only output respectively.
17pub trait ToolIO: Write + Sized {
18    /// The type of object that is expected for the [`Self::item`] call (or
19    /// any machine output writing functions that may be added by an
20    /// implementation)
21    type OutputItem;
22
23    /// Whether this supports structured machine output (like JSON).
24    fn supports_structured_output() -> bool {
25        false
26    }
27
28    /// Is a schema of the output type available.
29
30    fn has_schema() -> bool {
31        false
32    }
33
34    fn try_print_schema(&mut self) -> Result<()> {
35        Err(Error::SchemaFailure("No schema defined".into()))
36    }
37
38    /// Returns true if the receiver was configured to output for machines.
39    fn is_machine(&self) -> bool;
40
41    /// Returns an error stream that errors can be written to.
42    fn stderr(&mut self) -> &mut dyn Write;
43
44    /// Writes the value to standard output without a newline.
45    ///
46    /// This is a no-op if `is_machine` returns true.
47    fn print(&mut self, value: impl std::fmt::Display) -> Result<()> {
48        if !self.is_machine() {
49            write!(self, "{value}")?;
50        }
51        Ok(())
52    }
53
54    /// Writes the value to standard output with a newline.
55    ///
56    /// This is a no-op if `is_machine` returns true.
57    fn line(&mut self, value: impl std::fmt::Display) -> Result<()> {
58        if !self.is_machine() {
59            writeln!(self, "{value}")?;
60        }
61        Ok(())
62    }
63
64    /// Displays the item in whatever formatted style is most appropriate based
65    /// on is_machine and the underlying implementation
66    fn item(&mut self, value: &Self::OutputItem) -> Result<()>
67    where
68        Self::OutputItem: Display;
69}