diff options
Diffstat (limited to 'vendor/miette/src/handler.rs')
-rw-r--r-- | vendor/miette/src/handler.rs | 323 |
1 files changed, 0 insertions, 323 deletions
diff --git a/vendor/miette/src/handler.rs b/vendor/miette/src/handler.rs deleted file mode 100644 index e983a55..0000000 --- a/vendor/miette/src/handler.rs +++ /dev/null @@ -1,323 +0,0 @@ -use std::fmt; - -use crate::protocol::Diagnostic; -use crate::GraphicalReportHandler; -use crate::GraphicalTheme; -use crate::NarratableReportHandler; -use crate::ReportHandler; -use crate::ThemeCharacters; -use crate::ThemeStyles; - -/// Settings to control the color format used for graphical rendering. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub enum RgbColors { - /// Use RGB colors even if the terminal does not support them - Always, - /// Use RGB colors instead of ANSI if the terminal supports RGB - Preferred, - /// Always use ANSI, regardless of terminal support for RGB - Never, -} - -impl Default for RgbColors { - fn default() -> RgbColors { - RgbColors::Never - } -} - -/** -Create a custom [`MietteHandler`] from options. - -## Example - -```no_run -miette::set_hook(Box::new(|_| { - Box::new(miette::MietteHandlerOpts::new() - .terminal_links(true) - .unicode(false) - .context_lines(3) - .build()) -})) -# .unwrap(); -``` -*/ -#[derive(Default, Debug, Clone)] -pub struct MietteHandlerOpts { - pub(crate) linkify: Option<bool>, - pub(crate) width: Option<usize>, - pub(crate) theme: Option<GraphicalTheme>, - pub(crate) force_graphical: Option<bool>, - pub(crate) force_narrated: Option<bool>, - pub(crate) rgb_colors: RgbColors, - pub(crate) color: Option<bool>, - pub(crate) unicode: Option<bool>, - pub(crate) footer: Option<String>, - pub(crate) context_lines: Option<usize>, - pub(crate) tab_width: Option<usize>, - pub(crate) with_cause_chain: Option<bool>, -} - -impl MietteHandlerOpts { - /// Create a new `MietteHandlerOpts`. - pub fn new() -> Self { - Default::default() - } - - /// If true, specify whether the graphical handler will make codes be - /// clickable links in supported terminals. Defaults to auto-detection - /// based on known supported terminals. - pub fn terminal_links(mut self, linkify: bool) -> Self { - self.linkify = Some(linkify); - self - } - - /// Set a graphical theme for the handler when rendering in graphical mode. - /// Use [`force_graphical()`](`MietteHandlerOpts::force_graphical) to force - /// graphical mode. This option overrides - /// [`color()`](`MietteHandlerOpts::color). - pub fn graphical_theme(mut self, theme: GraphicalTheme) -> Self { - self.theme = Some(theme); - self - } - - /// Sets the width to wrap the report at. Defaults to 80. - pub fn width(mut self, width: usize) -> Self { - self.width = Some(width); - self - } - - /// Include the cause chain of the top-level error in the report. - pub fn with_cause_chain(mut self) -> Self { - self.with_cause_chain = Some(true); - self - } - - /// Do not include the cause chain of the top-level error in the report. - pub fn without_cause_chain(mut self) -> Self { - self.with_cause_chain = Some(false); - self - } - - /// If true, colors will be used during graphical rendering, regardless - /// of whether or not the terminal supports them. - /// - /// If false, colors will never be used. - /// - /// If unspecified, colors will be used only if the terminal supports them. - /// - /// The actual format depends on the value of - /// [`MietteHandlerOpts::rgb_colors`]. - pub fn color(mut self, color: bool) -> Self { - self.color = Some(color); - self - } - - /// Controls which color format to use if colors are used in graphical - /// rendering. - /// - /// The default is `Never`. - /// - /// This value does not control whether or not colors are being used in the - /// first place. That is handled by the [`MietteHandlerOpts::color`] - /// setting. If colors are not being used, the value of `rgb_colors` has - /// no effect. - pub fn rgb_colors(mut self, color: RgbColors) -> Self { - self.rgb_colors = color; - self - } - - /// If true, forces unicode display for graphical output. If set to false, - /// forces ASCII art display. - pub fn unicode(mut self, unicode: bool) -> Self { - self.unicode = Some(unicode); - self - } - - /// If true, graphical rendering will be used regardless of terminal - /// detection. - pub fn force_graphical(mut self, force: bool) -> Self { - self.force_graphical = Some(force); - self - } - - /// If true, forces use of the narrated renderer. - pub fn force_narrated(mut self, force: bool) -> Self { - self.force_narrated = Some(force); - self - } - - /// Set a footer to be displayed at the bottom of the report. - pub fn footer(mut self, footer: String) -> Self { - self.footer = Some(footer); - self - } - - /// Sets the number of context lines before and after a span to display. - pub fn context_lines(mut self, context_lines: usize) -> Self { - self.context_lines = Some(context_lines); - self - } - - /// Set the displayed tab width in spaces. - pub fn tab_width(mut self, width: usize) -> Self { - self.tab_width = Some(width); - self - } - - /// Builds a [`MietteHandler`] from this builder. - pub fn build(self) -> MietteHandler { - let graphical = self.is_graphical(); - let width = self.get_width(); - if !graphical { - let mut handler = NarratableReportHandler::new(); - if let Some(footer) = self.footer { - handler = handler.with_footer(footer); - } - if let Some(context_lines) = self.context_lines { - handler = handler.with_context_lines(context_lines); - } - if let Some(with_cause_chain) = self.with_cause_chain { - if with_cause_chain { - handler = handler.with_cause_chain(); - } else { - handler = handler.without_cause_chain(); - } - } - MietteHandler { - inner: Box::new(handler), - } - } else { - let linkify = self.use_links(); - let characters = match self.unicode { - Some(true) => ThemeCharacters::unicode(), - Some(false) => ThemeCharacters::ascii(), - None if supports_unicode::on(supports_unicode::Stream::Stderr) => { - ThemeCharacters::unicode() - } - None => ThemeCharacters::ascii(), - }; - let styles = if self.color == Some(false) { - ThemeStyles::none() - } else if let Some(color) = supports_color::on(supports_color::Stream::Stderr) { - match self.rgb_colors { - RgbColors::Always => ThemeStyles::rgb(), - RgbColors::Preferred if color.has_16m => ThemeStyles::rgb(), - _ => ThemeStyles::ansi(), - } - } else if self.color == Some(true) { - match self.rgb_colors { - RgbColors::Always => ThemeStyles::rgb(), - _ => ThemeStyles::ansi(), - } - } else { - ThemeStyles::none() - }; - let theme = self.theme.unwrap_or(GraphicalTheme { characters, styles }); - let mut handler = GraphicalReportHandler::new() - .with_width(width) - .with_links(linkify) - .with_theme(theme); - if let Some(with_cause_chain) = self.with_cause_chain { - if with_cause_chain { - handler = handler.with_cause_chain(); - } else { - handler = handler.without_cause_chain(); - } - } - if let Some(footer) = self.footer { - handler = handler.with_footer(footer); - } - if let Some(context_lines) = self.context_lines { - handler = handler.with_context_lines(context_lines); - } - if let Some(w) = self.tab_width { - handler = handler.tab_width(w); - } - MietteHandler { - inner: Box::new(handler), - } - } - } - - pub(crate) fn is_graphical(&self) -> bool { - if let Some(force_narrated) = self.force_narrated { - !force_narrated - } else if let Some(force_graphical) = self.force_graphical { - force_graphical - } else if let Ok(env) = std::env::var("NO_GRAPHICS") { - env == "0" - } else { - true - } - } - - // Detects known terminal apps based on env variables and returns true if - // they support rendering links. - pub(crate) fn use_links(&self) -> bool { - if let Some(linkify) = self.linkify { - linkify - } else { - supports_hyperlinks::on(supports_hyperlinks::Stream::Stderr) - } - } - - #[cfg(not(miri))] - pub(crate) fn get_width(&self) -> usize { - self.width.unwrap_or_else(|| { - terminal_size::terminal_size() - .unwrap_or((terminal_size::Width(80), terminal_size::Height(0))) - .0 - .0 as usize - }) - } - - #[cfg(miri)] - // miri doesn't support a syscall (specifically ioctl) - // performed by terminal_size, which causes test execution to fail - // so when miri is running we'll just fallback to a constant - pub(crate) fn get_width(&self) -> usize { - self.width.unwrap_or(80) - } -} - -/** -A [`ReportHandler`] that displays a given [`Report`](crate::Report) in a -quasi-graphical way, using terminal colors, unicode drawing characters, and -other such things. - -This is the default reporter bundled with `miette`. - -This printer can be customized by using -[`GraphicalReportHandler::new_themed()`] and handing it a [`GraphicalTheme`] of -your own creation (or using one of its own defaults). - -See [`set_hook`](crate::set_hook) for more details on customizing your global -printer. -*/ -#[allow(missing_debug_implementations)] -pub struct MietteHandler { - inner: Box<dyn ReportHandler + Send + Sync>, -} - -impl MietteHandler { - /// Creates a new [`MietteHandler`] with default settings. - pub fn new() -> Self { - Default::default() - } -} - -impl Default for MietteHandler { - fn default() -> Self { - MietteHandlerOpts::new().build() - } -} - -impl ReportHandler for MietteHandler { - fn debug(&self, diagnostic: &(dyn Diagnostic), f: &mut fmt::Formatter<'_>) -> fmt::Result { - if f.alternate() { - return fmt::Debug::fmt(diagnostic, f); - } - - self.inner.debug(diagnostic, f) - } -} |