ralph_workflow/json_parser/printer/
traits.rs1pub trait Printable: std::io::Write {
11 fn is_terminal(&self) -> bool;
16}
17
18#[derive(Debug)]
20pub struct StdoutPrinter {
21 stdout: Stdout,
22 is_terminal: bool,
23}
24
25impl StdoutPrinter {
26 #[must_use]
28 pub fn new() -> Self {
29 let is_terminal = std::io::stdout().is_terminal();
30 Self {
31 stdout: std::io::stdout(),
32 is_terminal,
33 }
34 }
35}
36
37impl Default for StdoutPrinter {
38 fn default() -> Self {
39 Self::new()
40 }
41}
42
43impl std::io::Write for StdoutPrinter {
44 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
45 self.stdout.write(buf)
46 }
47
48 fn flush(&mut self) -> io::Result<()> {
49 self.stdout.flush()
50 }
51}
52
53impl Printable for StdoutPrinter {
54 fn is_terminal(&self) -> bool {
55 self.is_terminal
56 }
57}
58
59#[derive(Debug)]
61#[cfg(any(test, feature = "test-utils"))]
62pub struct StderrPrinter {
63 stderr: Stderr,
64 is_terminal: bool,
65}
66
67#[cfg(any(test, feature = "test-utils"))]
68impl StderrPrinter {
69 #[must_use]
71 pub fn new() -> Self {
72 let is_terminal = std::io::stderr().is_terminal();
73 Self {
74 stderr: std::io::stderr(),
75 is_terminal,
76 }
77 }
78}
79
80#[cfg(any(test, feature = "test-utils"))]
81impl Default for StderrPrinter {
82 fn default() -> Self {
83 Self::new()
84 }
85}
86
87#[cfg(any(test, feature = "test-utils"))]
88impl std::io::Write for StderrPrinter {
89 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
90 self.stderr.write(buf)
91 }
92
93 fn flush(&mut self) -> io::Result<()> {
94 self.stderr.flush()
95 }
96}
97
98#[cfg(any(test, feature = "test-utils"))]
99impl Printable for StderrPrinter {
100 fn is_terminal(&self) -> bool {
101 self.is_terminal
102 }
103}
104
105pub type SharedPrinter = Rc<RefCell<dyn Printable>>;
110
111#[must_use]
113pub fn shared_stdout() -> SharedPrinter {
114 Rc::new(RefCell::new(StdoutPrinter::new()))
115}