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