kutil_cli/debug/
debuggable.rs

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