1 use std::fmt;
2 
3 use crate::{protocol::Diagnostic, ReportHandler};
4 
5 /**
6 [`ReportHandler`] that renders plain text and avoids extraneous graphics.
7 It's optimized for screen readers and braille users, but is also used in any
8 non-graphical environments, such as non-TTY output.
9 */
10 #[derive(Debug, Clone)]
11 pub struct DebugReportHandler;
12 
13 impl DebugReportHandler {
14     /// Create a new [`NarratableReportHandler`](crate::NarratableReportHandler)
15     /// There are no customization options.
new() -> Self16     pub const fn new() -> Self {
17         Self
18     }
19 }
20 
21 impl Default for DebugReportHandler {
default() -> Self22     fn default() -> Self {
23         Self::new()
24     }
25 }
26 
27 impl DebugReportHandler {
28     /// Render a [`Diagnostic`]. This function is mostly internal and meant to
29     /// be called by the toplevel [`ReportHandler`] handler, but is made public
30     /// to make it easier (possible) to test in isolation from global state.
render_report( &self, f: &mut fmt::Formatter<'_>, diagnostic: &(dyn Diagnostic), ) -> fmt::Result31     pub fn render_report(
32         &self,
33         f: &mut fmt::Formatter<'_>,
34         diagnostic: &(dyn Diagnostic),
35     ) -> fmt::Result {
36         let mut diag = f.debug_struct("Diagnostic");
37         diag.field("message", &format!("{}", diagnostic));
38         if let Some(code) = diagnostic.code() {
39             diag.field("code", &code.to_string());
40         }
41         if let Some(severity) = diagnostic.severity() {
42             diag.field("severity", &format!("{:?}", severity));
43         }
44         if let Some(url) = diagnostic.url() {
45             diag.field("url", &url.to_string());
46         }
47         if let Some(help) = diagnostic.help() {
48             diag.field("help", &help.to_string());
49         }
50         if let Some(labels) = diagnostic.labels() {
51             let labels: Vec<_> = labels.collect();
52             diag.field("labels", &format!("{:?}", labels));
53         }
54         if let Some(cause) = diagnostic.diagnostic_source() {
55             diag.field("caused by", &format!("{:?}", cause));
56         }
57         diag.finish()?;
58         writeln!(f)?;
59         writeln!(f, "NOTE: If you're looking for the fancy error reports, install miette with the `fancy` feature, or write your own and hook it up with miette::set_hook().")
60     }
61 }
62 
63 impl ReportHandler for DebugReportHandler {
debug(&self, diagnostic: &(dyn Diagnostic), f: &mut fmt::Formatter<'_>) -> fmt::Result64     fn debug(&self, diagnostic: &(dyn Diagnostic), f: &mut fmt::Formatter<'_>) -> fmt::Result {
65         if f.alternate() {
66             return fmt::Debug::fmt(diagnostic, f);
67         }
68 
69         self.render_report(f, diagnostic)
70     }
71 }
72