kutil_cli/debug/
debuggable.rs

1use super::{context::*, format::*, theme::*};
2
3use std::io::*;
4
5//
6// Debuggable
7//
8
9/// Can write a debug representation of itself that can be indented, styled, and multiline.
10///
11/// Designed to support complex nested hierarchies.
12pub trait Debuggable {
13    /// Write the debug representation for the context.
14    ///
15    /// Required behavior for implementations:
16    ///
17    /// 1. Representations *must not* end in a newline.
18    /// 2. If *not* starting with a newline and *not* empty, *must* call [DebugContext::separate] first.
19    /// 3. All lines *after* the first (but *not* the first) *must* start with the [DebugContext] indentation.
20    fn write_debug_for<WriteT>(&self, writer: &mut WriteT, context: &DebugContext) -> Result<()>
21    where
22        WriteT: Write;
23
24    // write_debug
25
26    /// Write the debug representation with the default theme and a final newline.
27    fn write_debug_with_format<WriteT>(&self, writer: &mut WriteT, format: DebugFormat) -> Result<()>
28    where
29        WriteT: Write,
30    {
31        self.write_debug_for(writer, &DebugContext::new(&Theme::default()).with_format(format))?;
32        writeln!(writer)
33    }
34
35    /// Write the debug representation with the default theme and a final newline.
36    fn write_debug<WriteT>(&self, writer: &mut WriteT) -> Result<()>
37    where
38        WriteT: Write,
39    {
40        self.write_debug_with_format(writer, DebugFormat::default())
41    }
42
43    /// Write the debug representation with the plain theme and a final newline.
44    fn write_debug_plain_with_format<WriteT>(&self, writer: &mut WriteT, format: DebugFormat) -> Result<()>
45    where
46        WriteT: Write,
47    {
48        self.write_debug_for(writer, &DebugContext::new(&Theme::plain()).with_format(format))?;
49        writeln!(writer)
50    }
51
52    /// Write the debug representation with the plain theme and a final newline.
53    fn write_debug_plain<WriteT>(&self, writer: &mut WriteT) -> Result<()>
54    where
55        WriteT: Write,
56    {
57        self.write_debug_with_format(writer, DebugFormat::default())
58    }
59
60    // print_debug
61
62    /// Print the debug representation to [anstream::stdout] with the default theme and a final newline.
63    ///
64    /// Panics on write [Error].
65    fn print_debug_with_format(&self, format: DebugFormat) {
66        self.write_debug_with_format(&mut anstream::stdout(), format).unwrap();
67    }
68
69    /// Print the debug representation to [anstream::stdout] with the default theme and a final newline.
70    ///
71    /// Panics on write [Error].
72    fn print_debug(&self) {
73        self.print_debug_with_format(DebugFormat::default());
74    }
75
76    /// Print the debug representation to [stdout] with the plain theme and a final newline.
77    ///
78    /// Panics on write [Error].
79    fn print_debug_plain_with_format(&self, format: DebugFormat) {
80        self.write_debug_plain_with_format(&mut stdout(), format).unwrap();
81    }
82
83    /// Print the debug representation to [stdout] with the plain theme and a final newline.
84    ///
85    /// Panics on write [Error].
86    fn print_debug_plain(&self) {
87        self.print_debug_plain_with_format(DebugFormat::default());
88    }
89
90    // eprint_debug
91
92    /// Print the debug representation to [anstream::stderr] with the default theme and a final newline.
93    ///
94    /// Panics on write [Error].
95    fn eprint_debug_with_format(&self, format: DebugFormat) {
96        self.write_debug_with_format(&mut anstream::stdout(), format).unwrap();
97    }
98
99    /// Print the debug representation to [anstream::stderr] with the default theme and a final newline.
100    ///
101    /// Panics on write [Error].
102    fn eprint_debug(&self) {
103        self.eprint_debug_with_format(DebugFormat::default());
104    }
105
106    /// Print the debug representation to [stderr] with the plain theme and a final newline.
107    ///
108    /// Panics on write [Error].
109    fn eprint_debug_plain_with_format(&self, format: DebugFormat) {
110        self.write_debug_plain_with_format(&mut stdout(), format).unwrap();
111    }
112
113    /// Print the debug representation to [stderr] with the plain theme and a final newline.
114    ///
115    /// Panics on write [Error].
116    fn eprint_debug_plain(&self) {
117        self.eprint_debug_plain_with_format(DebugFormat::default());
118    }
119
120    /// Capture [write_debug_for](Debuggable::write_debug_for) into a string.
121    fn to_debug_string_with_format(&self, theme: &Theme, format: DebugFormat) -> Result<String> {
122        let mut writer = BufWriter::new(Vec::new());
123        self.write_debug_for(&mut writer, &DebugContext::new(theme).with_format(format))?;
124        match String::from_utf8(writer.into_inner().unwrap().into()) {
125            Ok(string) => Ok(string),
126            Err(error) => Err(Error::other(format!("{}", error))),
127        }
128    }
129
130    /// Capture [write_debug_for](Debuggable::write_debug_for) into a string.
131    fn to_debug_string(&self, theme: &Theme) -> Result<String> {
132        self.to_debug_string_with_format(theme, DebugFormat::default())
133    }
134}