diff --git a/src/handler.rs b/src/handler.rs index e983a55..536efd4 100644 --- a/src/handler.rs +++ b/src/handler.rs @@ -25,6 +25,9 @@ impl Default for RgbColors { } } +/// Function to format a message before rendering. +pub type MessageFormatter = dyn Fn(String) -> String; + /** Create a custom [`MietteHandler`] from options. @@ -55,6 +58,7 @@ pub struct MietteHandlerOpts { pub(crate) context_lines: Option, pub(crate) tab_width: Option, pub(crate) with_cause_chain: Option, + pub(crate) message_formatter: Option>, } impl MietteHandlerOpts { @@ -164,6 +168,11 @@ impl MietteHandlerOpts { self } + pub fn message_formatter(mut self, formatter: F) -> Self { + self.message_formatter = Some(Box::new(formatter)); + self + } + /// Builds a [`MietteHandler`] from this builder. pub fn build(self) -> MietteHandler { let graphical = self.is_graphical(); @@ -233,6 +242,9 @@ impl MietteHandlerOpts { if let Some(w) = self.tab_width { handler = handler.tab_width(w); } + if let Some(formatter) = self.message_formatter { + handler = handler.with_message_formatter(formatter); + } MietteHandler { inner: Box::new(handler), } diff --git a/src/handlers/graphical.rs b/src/handlers/graphical.rs index 71df2cb..09e18e3 100644 --- a/src/handlers/graphical.rs +++ b/src/handlers/graphical.rs @@ -6,7 +6,9 @@ use unicode_width::UnicodeWidthChar; use crate::diagnostic_chain::DiagnosticChain; use crate::handlers::theme::*; use crate::protocol::{Diagnostic, Severity}; -use crate::{LabeledSpan, MietteError, ReportHandler, SourceCode, SourceSpan, SpanContents}; +use crate::{ + LabeledSpan, MessageFormatter, MietteError, ReportHandler, SourceCode, SourceSpan, SpanContents, +}; /** A [`ReportHandler`] that displays a given [`Report`](crate::Report) in a @@ -30,6 +32,7 @@ pub struct GraphicalReportHandler { pub(crate) context_lines: usize, pub(crate) tab_width: usize, pub(crate) with_cause_chain: bool, + pub(crate) message_formatter: Option>, } #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -51,6 +54,7 @@ impl GraphicalReportHandler { context_lines: 1, tab_width: 4, with_cause_chain: true, + message_formatter: None, } } @@ -64,6 +68,7 @@ impl GraphicalReportHandler { context_lines: 1, tab_width: 4, with_cause_chain: true, + message_formatter: None, } } @@ -133,6 +138,11 @@ impl GraphicalReportHandler { self.context_lines = lines; self } + + pub fn with_message_formatter(mut self, formatter: F) -> Self { + self.message_formatter = Some(Box::new(formatter)); + self + } } impl Default for GraphicalReportHandler { @@ -214,8 +224,13 @@ impl GraphicalReportHandler { let opts = textwrap::Options::new(width) .initial_indent(&initial_indent) .subsequent_indent(&rest_indent); + let mut message = diagnostic.to_string(); - writeln!(f, "{}", textwrap::fill(&diagnostic.to_string(), opts))?; + if let Some(formatter) = self.message_formatter { + message = formatter(message); + } + + writeln!(f, "{}", textwrap::fill(&message, opts))?; if !self.with_cause_chain { return Ok(());