mirror of https://github.com/zkat/miette.git
feat(printer): rename default printer and consistify some naming conventions with printing
BREAKING CHANGE: This is a significant API break.
This commit is contained in:
parent
e980b72373
commit
aafa4a3de1
|
|
@ -8,34 +8,52 @@ use crate::protocol::{Diagnostic, DiagnosticReportPrinter, DiagnosticSnippet, Se
|
|||
use crate::{SourceSpan, SpanContents};
|
||||
|
||||
/**
|
||||
Reference implementation of the [DiagnosticReportPrinter] trait. This is generally
|
||||
good enough for simple use-cases, and is the default one installed with `miette`,
|
||||
but you might want to implement your own if you want custom reporting for your
|
||||
tool or app.
|
||||
A [DiagnosticReportPrinter] that displays a given [crate::DiagnosticReport] 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 `new_themed()` and handing it a [GraphicalTheme] of your own creation (or using one of its own defaults!)
|
||||
|
||||
See [crate::set_printer] for more details on customizing your global printer.
|
||||
|
||||
## Example
|
||||
|
||||
```
|
||||
use miette::{GraphicalReportPrinter, GraphicalTheme};
|
||||
miette::set_printer(GraphicalReportPrinter::new_themed(GraphicalTheme::unicode_nocolor()));
|
||||
```
|
||||
*/
|
||||
pub struct DefaultReportPrinter {
|
||||
pub(crate) theme: MietteTheme,
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct GraphicalReportPrinter {
|
||||
pub(crate) theme: GraphicalTheme,
|
||||
}
|
||||
|
||||
impl DefaultReportPrinter {
|
||||
impl GraphicalReportPrinter {
|
||||
/// Create a new [GraphicalReportPrinter] with the default
|
||||
/// [GraphicalTheme]. This will use both unicode characters and colors.
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
theme: MietteTheme::default(),
|
||||
theme: GraphicalTheme::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_themed(theme: MietteTheme) -> Self {
|
||||
///Create a new [GraphicalReportPrinter] with a given [GraphicalTheme].
|
||||
pub fn new_themed(theme: GraphicalTheme) -> Self {
|
||||
Self { theme }
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for DefaultReportPrinter {
|
||||
impl Default for GraphicalReportPrinter {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl DefaultReportPrinter {
|
||||
impl GraphicalReportPrinter {
|
||||
/// Render a [Diagnostic]. This function is mostly internal and meant to
|
||||
/// be called by the toplevel [DiagnosticReportPrinter] handler, but is
|
||||
/// made public to make it easier (possible) to test in isolation from
|
||||
/// global state.
|
||||
pub fn render_report(
|
||||
&self,
|
||||
f: &mut impl fmt::Write,
|
||||
|
|
@ -116,7 +134,7 @@ impl DefaultReportPrinter {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn render_snippet(&self, f: &mut impl fmt::Write, snippet: &DiagnosticSnippet) -> fmt::Result {
|
||||
fn render_snippet(&self, f: &mut impl fmt::Write, snippet: &DiagnosticSnippet<'_>) -> fmt::Result {
|
||||
let (contents, lines) = self.get_lines(snippet)?;
|
||||
|
||||
// Highlights are the bits we're going to underline in our overall
|
||||
|
|
@ -408,7 +426,7 @@ impl DefaultReportPrinter {
|
|||
|
||||
fn get_lines<'a>(
|
||||
&'a self,
|
||||
snippet: &'a DiagnosticSnippet,
|
||||
snippet: &'a DiagnosticSnippet<'_>,
|
||||
) -> Result<(Box<dyn SpanContents + 'a>, Vec<Line>), fmt::Error> {
|
||||
let context_data = snippet
|
||||
.source
|
||||
|
|
@ -463,7 +481,7 @@ impl DefaultReportPrinter {
|
|||
}
|
||||
}
|
||||
|
||||
impl DiagnosticReportPrinter for DefaultReportPrinter {
|
||||
impl DiagnosticReportPrinter for GraphicalReportPrinter {
|
||||
fn debug(&self, diagnostic: &(dyn Diagnostic), f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
if f.alternate() {
|
||||
return fmt::Debug::fmt(diagnostic, f);
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
/*!
|
||||
Basic reporter for Diagnostics. Probably good enough for most use-cases,
|
||||
but largely meant to be an example.
|
||||
Reporters included with `miette`.
|
||||
*/
|
||||
use std::fmt;
|
||||
|
||||
|
|
@ -10,11 +9,11 @@ use once_cell::sync::OnceCell;
|
|||
use crate::protocol::{Diagnostic, DiagnosticReportPrinter, Severity};
|
||||
use crate::MietteError;
|
||||
|
||||
pub use default_printer::*;
|
||||
pub use graphical_printer::*;
|
||||
pub use narratable_printer::*;
|
||||
pub use theme::*;
|
||||
|
||||
mod default_printer;
|
||||
mod graphical_printer;
|
||||
mod narratable_printer;
|
||||
mod theme;
|
||||
|
||||
|
|
@ -22,8 +21,8 @@ static REPORTER: OnceCell<Box<dyn DiagnosticReportPrinter + Send + Sync + 'stati
|
|||
OnceCell::new();
|
||||
|
||||
/// Set the global [DiagnosticReportPrinter] that will be used when you report
|
||||
/// using [DiagnosticReport].
|
||||
pub fn set_reporter(
|
||||
/// using [crate::DiagnosticReport].
|
||||
pub fn set_printer(
|
||||
reporter: impl DiagnosticReportPrinter + Send + Sync + 'static,
|
||||
) -> Result<(), MietteError> {
|
||||
REPORTER
|
||||
|
|
@ -31,9 +30,9 @@ pub fn set_reporter(
|
|||
.map_err(|_| MietteError::SetPrinterFailure)
|
||||
}
|
||||
|
||||
/// Used by [DiagnosticReport] to fetch the reporter that will be used to
|
||||
/// Used by [crate::DiagnosticReport] to fetch the reporter that will be used to
|
||||
/// print stuff out.
|
||||
pub fn get_reporter() -> &'static (dyn DiagnosticReportPrinter + Send + Sync + 'static) {
|
||||
pub(crate) fn get_printer() -> &'static (dyn DiagnosticReportPrinter + Send + Sync + 'static) {
|
||||
&**REPORTER.get_or_init(get_default_printer)
|
||||
}
|
||||
|
||||
|
|
@ -46,8 +45,8 @@ fn get_default_printer() -> Box<dyn DiagnosticReportPrinter + Send + Sync + 'sta
|
|||
atty::is(Stream::Stdout) && atty::is(Stream::Stderr) && !ci_info::is_ci()
|
||||
};
|
||||
if fancy {
|
||||
Box::new(DefaultReportPrinter {
|
||||
theme: MietteTheme::default(),
|
||||
Box::new(GraphicalReportPrinter {
|
||||
theme: GraphicalTheme::default(),
|
||||
})
|
||||
} else {
|
||||
Box::new(NarratableReportPrinter)
|
||||
|
|
@ -55,9 +54,9 @@ fn get_default_printer() -> Box<dyn DiagnosticReportPrinter + Send + Sync + 'sta
|
|||
}
|
||||
|
||||
/// Literally what it says on the tin.
|
||||
pub struct JokeReporter;
|
||||
pub struct JokePrinter;
|
||||
|
||||
impl DiagnosticReportPrinter for JokeReporter {
|
||||
impl DiagnosticReportPrinter for JokePrinter {
|
||||
fn debug(&self, diagnostic: &(dyn Diagnostic), f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
if f.alternate() {
|
||||
return fmt::Debug::fmt(diagnostic, f);
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ good enough for simple use-cases, and is the default one installed with `miette`
|
|||
but you might want to implement your own if you want custom reporting for your
|
||||
tool or app.
|
||||
*/
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct NarratableReportPrinter;
|
||||
|
||||
impl NarratableReportPrinter {
|
||||
|
|
|
|||
|
|
@ -1,55 +1,91 @@
|
|||
use atty::Stream;
|
||||
use owo_colors::Style;
|
||||
|
||||
pub struct MietteTheme {
|
||||
pub characters: MietteCharacters,
|
||||
pub styles: MietteStyles,
|
||||
/**
|
||||
Theme used by [crate::GraphicalReportPrinter] to render fancy [crate::Diagnostic] reports.
|
||||
|
||||
A theme consists of two things: the set of characters to be used for drawing,
|
||||
and the [owo_colors::Style]s to be used to paint various items.
|
||||
|
||||
You can create your own custom graphical theme using this type, or you can use
|
||||
one of the predefined ones using the methods below.
|
||||
*/
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct GraphicalTheme {
|
||||
/// Characters to be used for drawing.
|
||||
pub characters: ThemeCharacters,
|
||||
/// Styles to be used for painting.
|
||||
pub styles: ThemeStyles,
|
||||
}
|
||||
|
||||
impl MietteTheme {
|
||||
pub fn basic() -> Self {
|
||||
impl GraphicalTheme {
|
||||
/// ASCII-art-based graphical drawing, with ANSI styling.
|
||||
pub fn ascii() -> Self {
|
||||
Self {
|
||||
characters: MietteCharacters::ascii(),
|
||||
styles: MietteStyles::ansi(),
|
||||
characters: ThemeCharacters::ascii(),
|
||||
styles: ThemeStyles::ansi(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Graphical theme that draws using both ansi colors and unicode characters.
|
||||
pub fn unicode() -> Self {
|
||||
Self {
|
||||
characters: MietteCharacters::unicode(),
|
||||
styles: MietteStyles::ansi(),
|
||||
characters: ThemeCharacters::unicode(),
|
||||
styles: ThemeStyles::ansi(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Graphical theme that draws in monochrome, while still using unicode
|
||||
/// characters.
|
||||
pub fn unicode_nocolor() -> Self {
|
||||
Self {
|
||||
characters: MietteCharacters::unicode(),
|
||||
styles: MietteStyles::none(),
|
||||
characters: ThemeCharacters::unicode(),
|
||||
styles: ThemeStyles::none(),
|
||||
}
|
||||
}
|
||||
|
||||
/// A "basic" graphical theme that skips colors and unicode characters and
|
||||
/// just does monochrome ascii art. If you want a completely non-graphical
|
||||
/// rendering of your `Diagnostic`s, check out
|
||||
/// [crate::NarratableReportPrinter], or write your own
|
||||
/// [crate::DiagnosticReportPrinter]!
|
||||
pub fn none() -> Self {
|
||||
Self {
|
||||
characters: MietteCharacters::ascii(),
|
||||
styles: MietteStyles::none(),
|
||||
characters: ThemeCharacters::ascii(),
|
||||
styles: ThemeStyles::none(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for MietteTheme {
|
||||
impl Default for GraphicalTheme {
|
||||
fn default() -> Self {
|
||||
match std::env::var("NO_COLOR") {
|
||||
_ if !atty::is(Stream::Stdout) || !atty::is(Stream::Stderr) => Self::basic(),
|
||||
_ if !atty::is(Stream::Stdout) || !atty::is(Stream::Stderr) => Self::ascii(),
|
||||
Ok(string) if string != "0" => Self::unicode_nocolor(),
|
||||
_ => Self::unicode(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MietteStyles {
|
||||
/**
|
||||
Styles for various parts of graphical rendering for the [crate::GraphicalReportPrinter].
|
||||
*/
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ThemeStyles {
|
||||
/// Style to apply to things highlighted as "error".
|
||||
pub error: Style,
|
||||
/// Style to apply to things highlighted as "warning".
|
||||
pub warning: Style,
|
||||
/// Style to apply to things highlighted as "advice".
|
||||
pub advice: Style,
|
||||
/// Style to apply to the diagnostic code.
|
||||
pub code: Style,
|
||||
/// Style to apply to the help text.
|
||||
pub help: Style,
|
||||
/// Style to apply to the filename/source name.
|
||||
pub filename: Style,
|
||||
/// Styles to cycle through (using `.iter().cycle()`), to render the lines
|
||||
/// and text for diagnostic highlights.
|
||||
pub highlights: Vec<Style>,
|
||||
}
|
||||
|
||||
|
|
@ -57,7 +93,8 @@ fn style() -> Style {
|
|||
Style::new()
|
||||
}
|
||||
|
||||
impl MietteStyles {
|
||||
impl ThemeStyles {
|
||||
/// ANSI color-based styles.
|
||||
pub fn ansi() -> Self {
|
||||
Self {
|
||||
error: style().red(),
|
||||
|
|
@ -74,6 +111,7 @@ impl MietteStyles {
|
|||
}
|
||||
}
|
||||
|
||||
/// No styling. Just regular ol' monochrome.
|
||||
pub fn none() -> Self {
|
||||
Self {
|
||||
error: style(),
|
||||
|
|
@ -88,9 +126,13 @@ impl MietteStyles {
|
|||
}
|
||||
|
||||
// ---------------------------------------
|
||||
// All code below here was taken from ariadne here:
|
||||
// Most of these characters were taken from
|
||||
// https://github.com/zesterer/ariadne/blob/e3cb394cb56ecda116a0a1caecd385a49e7f6662/src/draw.rs
|
||||
pub struct MietteCharacters {
|
||||
|
||||
/// Characters to be used when drawing when using [crate::GraphicalReportPrinter].
|
||||
#[allow(missing_docs)]
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub struct ThemeCharacters {
|
||||
pub hbar: char,
|
||||
pub vbar: char,
|
||||
pub xbar: char,
|
||||
|
|
@ -121,7 +163,8 @@ pub struct MietteCharacters {
|
|||
pub point_right: char,
|
||||
}
|
||||
|
||||
impl MietteCharacters {
|
||||
impl ThemeCharacters {
|
||||
/// Fancy unicode-based graphical elements.
|
||||
pub fn unicode() -> Self {
|
||||
Self {
|
||||
hbar: '─',
|
||||
|
|
@ -149,6 +192,7 @@ impl MietteCharacters {
|
|||
}
|
||||
}
|
||||
|
||||
/// ASCII-art-based graphical elements. Works well on older terminals.
|
||||
pub fn ascii() -> Self {
|
||||
Self {
|
||||
hbar: '-',
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use miette::{
|
||||
DefaultReportPrinter, Diagnostic, DiagnosticReport, MietteError, MietteTheme,
|
||||
GraphicalReportPrinter, Diagnostic, DiagnosticReport, MietteError, GraphicalTheme,
|
||||
NarratableReportPrinter, SourceSpan,
|
||||
};
|
||||
use thiserror::Error;
|
||||
|
|
@ -8,7 +8,7 @@ fn fmt_report(diag: DiagnosticReport) -> String {
|
|||
let mut out = String::new();
|
||||
// Mostly for dev purposes.
|
||||
if std::env::var("STYLE").is_ok() {
|
||||
DefaultReportPrinter::new_themed(MietteTheme::unicode())
|
||||
GraphicalReportPrinter::new_themed(GraphicalTheme::unicode())
|
||||
.render_report(&mut out, diag.inner())
|
||||
.unwrap();
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use miette::{
|
||||
DefaultReportPrinter, Diagnostic, DiagnosticReport, MietteError, MietteTheme,
|
||||
GraphicalReportPrinter, Diagnostic, DiagnosticReport, MietteError, GraphicalTheme,
|
||||
NarratableReportPrinter, SourceSpan,
|
||||
};
|
||||
use thiserror::Error;
|
||||
|
|
@ -8,7 +8,7 @@ fn fmt_report(diag: DiagnosticReport) -> String {
|
|||
let mut out = String::new();
|
||||
// Mostly for dev purposes.
|
||||
if std::env::var("STYLE").is_ok() {
|
||||
DefaultReportPrinter::new_themed(MietteTheme::unicode())
|
||||
GraphicalReportPrinter::new_themed(GraphicalTheme::unicode())
|
||||
.render_report(&mut out, diag.inner())
|
||||
.unwrap();
|
||||
} else if std::env::var("NARRATED").is_ok() {
|
||||
|
|
@ -16,7 +16,7 @@ fn fmt_report(diag: DiagnosticReport) -> String {
|
|||
.render_report(&mut out, diag.inner())
|
||||
.unwrap();
|
||||
} else {
|
||||
DefaultReportPrinter::new_themed(MietteTheme::unicode_nocolor())
|
||||
GraphicalReportPrinter::new_themed(GraphicalTheme::unicode_nocolor())
|
||||
.render_report(&mut out, diag.inner())
|
||||
.unwrap();
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue