diff --git a/Cargo.toml b/Cargo.toml index c154b8e6..7381688e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,6 @@ owo-colors = "2.0.0" atty = "0.2.14" ci_info = "0.14.2" indenter = "0.3.0" -pyo3 = { version = "0.13", optional = true, default-features = false } [dev-dependencies] semver = "1.0.4" @@ -28,7 +27,6 @@ semver = "1.0.4" futures = { version = "0.3", default-features = false } rustversion = "1.0" trybuild = { version = "1.0.19", features = ["diff"] } -backtrace = "0.3.46" anyhow = "1.0.28" syn = { version = "1.0", features = ["full"] } diff --git a/README.md b/README.md index 14181ec2..6e954c82 100644 --- a/README.md +++ b/README.md @@ -45,11 +45,11 @@ diagnostic error code: ruget::api::bad_json - Unique error codes on every [Diagnostic]. - Custom links to get more details on error codes. - Super handy derive macro for defining diagnostic metadata. -- Lightweight [`anyhow`](https://docs.rs/anyhow)/[`eyre`](https://docs.rs/eyre)-style error wrapper type, [DiagnosticReport], +- [`anyhow`](https://docs.rs/anyhow)/[`eyre`](https://docs.rs/eyre)-compatible error wrapper type, [Report], which can be returned from `main`. - Generic support for arbitrary [Source]s for snippet data, with default support for `String`s included. -The `miette` crate also comes bundled with a default [DiagnosticReportPrinter] with the following features: +The `miette` crate also comes bundled with a default [ReportHandler] with the following features: - Fancy graphical [diagnostic output](#about), using ANSI/Unicode text - single- and multi-line highlighting support @@ -191,7 +191,7 @@ Application code tends to work a little differently than libraries. You don't always need or care to define dedicated error wrappers for errors coming from external libraries and tools. -For this situation, `miette` includes two tools: [DiagnosticReport] and +For this situation, `miette` includes two tools: [Report] and [IntoDiagnostic]. They work in tandem to make it easy to convert regular `std::error::Error`s into [Diagnostic]s. Additionally, there's a [DiagnosticResult] type alias that you can use to be more terse: @@ -330,7 +330,7 @@ pub struct MyErrorType { [`color-eyre`](https://crates.io/crates/color-eyre): these two enormously influential error handling libraries have pushed forward the experience of application-level error handling and error reporting. `miette`'s - `DiagnosticReport` type is an attempt at a very very rough version of their + `Report` type is an attempt at a very very rough version of their `Report` types. - [`thiserror`](https://crates.io/crates/thiserror) for setting the standard for library-level error definitions, and for being the inspiration behind diff --git a/src/error.rs b/src/error.rs index bf02d12e..76a50a95 100644 --- a/src/error.rs +++ b/src/error.rs @@ -24,9 +24,9 @@ pub enum MietteError { )] OutOfBounds, - /// Returned when installing a [crate::DiagnosticReportPrinter] failed. + /// Returned when installing a [crate::ReportHandler] failed. /// Typically, this will be because [crate::set_printer] was called twice. - #[error("Failed to install DiagnosticReportPrinter")] + #[error("Failed to install ReportHandler")] #[diagnostic(code(miette::set_printer_failed), url(docsrs))] SetPrinterFailure, } diff --git a/src/eyreish/backtrace.rs b/src/eyreish/backtrace.rs deleted file mode 100644 index 6c00d7fa..00000000 --- a/src/eyreish/backtrace.rs +++ /dev/null @@ -1,22 +0,0 @@ -#[cfg(backtrace)] -pub(crate) use std::backtrace::Backtrace; - -#[cfg(not(backtrace))] -pub(crate) enum Backtrace {} - -#[cfg(backtrace)] -macro_rules! backtrace_if_absent { - ($err:expr) => { - match $err.backtrace() { - Some(_) => None, - None => Some(Backtrace::capture()), - } - }; -} - -#[cfg(not(backtrace))] -macro_rules! backtrace_if_absent { - ($err:expr) => { - None - }; -} diff --git a/src/eyreish/context.rs b/src/eyreish/context.rs index 18f4989f..f087eeba 100644 --- a/src/eyreish/context.rs +++ b/src/eyreish/context.rs @@ -4,9 +4,6 @@ use core::fmt::{self, Debug, Display, Write}; use std::error::Error as StdError; -#[cfg(backtrace)] -use std::backtrace::Backtrace; - use crate::Diagnostic; mod ext { @@ -147,11 +144,6 @@ where D: Display, E: StdError + 'static, { - #[cfg(backtrace)] - fn backtrace(&self) -> Option<&Backtrace> { - self.error.backtrace() - } - fn source(&self) -> Option<&(dyn StdError + 'static)> { Some(&self.error) } diff --git a/src/eyreish/error.rs b/src/eyreish/error.rs index 14f05963..383a45c9 100644 --- a/src/eyreish/error.rs +++ b/src/eyreish/error.rs @@ -4,7 +4,7 @@ use core::mem::{self, ManuallyDrop}; use core::ptr::{self, NonNull}; use std::error::Error as StdError; -use super::EyreHandler; +use super::ReportHandler; use super::Report; use crate::chain::Chain; use crate::Diagnostic; @@ -193,7 +193,7 @@ impl Report { unsafe fn construct( error: E, vtable: &'static ErrorVTable, - handler: Option>, + handler: Option>, ) -> Self where E: Diagnostic + Send + Sync + 'static, @@ -438,24 +438,24 @@ impl Report { } /// Get a reference to the Handler for this Report. - pub fn handler(&self) -> &dyn EyreHandler { + pub fn handler(&self) -> &dyn ReportHandler { self.inner.handler.as_ref().unwrap().as_ref() } /// Get a mutable reference to the Handler for this Report. - pub fn handler_mut(&mut self) -> &mut dyn EyreHandler { + pub fn handler_mut(&mut self) -> &mut dyn ReportHandler { self.inner.handler.as_mut().unwrap().as_mut() } /// Get a reference to the Handler for this Report. #[doc(hidden)] - pub fn context(&self) -> &dyn EyreHandler { + pub fn context(&self) -> &dyn ReportHandler { self.inner.handler.as_ref().unwrap().as_ref() } /// Get a mutable reference to the Handler for this Report. #[doc(hidden)] - pub fn context_mut(&mut self) -> &mut dyn EyreHandler { + pub fn context_mut(&mut self) -> &mut dyn ReportHandler { self.inner.handler.as_mut().unwrap().as_mut() } } @@ -680,7 +680,7 @@ where #[repr(C)] pub(crate) struct ErrorImpl { vtable: &'static ErrorVTable, - pub(crate) handler: Option>, + pub(crate) handler: Option>, // NOTE: Don't use directly. Use only through vtable. Erased type may have // different alignment. _object: E, @@ -789,6 +789,3 @@ impl AsRef for Report { &**self } } - -#[cfg(feature = "pyo3")] -mod pyo3_compat; diff --git a/src/eyreish/error/pyo3_compat.rs b/src/eyreish/error/pyo3_compat.rs deleted file mode 100644 index b70b6a54..00000000 --- a/src/eyreish/error/pyo3_compat.rs +++ /dev/null @@ -1,7 +0,0 @@ -use crate::Report; - -impl From for pyo3::PyErr { - fn from(error: Report) -> Self { - pyo3::exceptions::PyRuntimeError::new_err(format!("{:?}", error)) - } -} diff --git a/src/eyreish/into_diagnostic.rs b/src/eyreish/into_diagnostic.rs index 9c5b5ab6..3e03694d 100644 --- a/src/eyreish/into_diagnostic.rs +++ b/src/eyreish/into_diagnostic.rs @@ -1,5 +1,3 @@ -use std::fmt; - use thiserror::Error; use crate::{Diagnostic, Report}; diff --git a/src/eyreish/mod.rs b/src/eyreish/mod.rs index b60bf261..34871cc1 100644 --- a/src/eyreish/mod.rs +++ b/src/eyreish/mod.rs @@ -1,47 +1,37 @@ -#![cfg_attr(backtrace, feature(backtrace))] #![cfg_attr(doc_cfg, feature(doc_cfg))] #![allow( clippy::needless_doctest_main, clippy::new_ret_no_self, clippy::wrong_self_convention )] - -#[macro_use] -mod backtrace; -mod context; -mod error; -mod fmt; -mod into_diagnostic; -mod kind; -mod macros; -mod wrapper; - -pub use into_diagnostic::*; - -use std::error::Error as StdError; - -use self::backtrace::Backtrace; use core::fmt::Display; use core::mem::ManuallyDrop; -use error::ErrorImpl; -// pub use eyre as format_err; -// /// Compatibility re-export of `eyre` for interopt with `anyhow` -// pub use eyre as anyhow; +use std::error::Error as StdError; + use atty::Stream; use once_cell::sync::OnceCell; -// #[doc(hidden)] -// pub use DefaultHandler as DefaultContext; + #[doc(hidden)] -pub use EyreHandler as EyreContext; +pub use ReportHandler as EyreContext; #[doc(hidden)] pub use Report as ErrReport; /// Compatibility re-export of `Report` for interop with `anyhow` pub use Report as Error; /// Compatibility re-export of `WrapErr` for interop with `anyhow` pub use WrapErr as Context; +pub use into_diagnostic::*; -use crate::{Diagnostic, GraphicalReportPrinter, NarratableReportPrinter}; +use error::ErrorImpl; +use crate::{Diagnostic, GraphicalReportHandler, NarratableReportHandler}; + +mod context; +mod error; +mod fmt; +mod into_diagnostic; +mod kind; +mod macros; +mod wrapper; /** Core Diagnostic wrapper type. @@ -51,7 +41,7 @@ pub struct Report { } type ErrorHook = - Box Box + Sync + Send + 'static>; + Box Box + Sync + Send + 'static>; static HOOK: OnceCell = OnceCell::new(); @@ -77,10 +67,8 @@ pub fn set_hook(hook: ErrorHook) -> Result<(), InstallError> { #[cfg_attr(track_caller, track_caller)] #[cfg_attr(not(track_caller), allow(unused_mut))] -fn capture_handler(error: &(dyn Diagnostic + 'static)) -> Box { - let hook = HOOK - .get_or_init(|| Box::new(get_default_printer)) - .as_ref(); +fn capture_handler(error: &(dyn Diagnostic + 'static)) -> Box { + let hook = HOOK.get_or_init(|| Box::new(get_default_printer)).as_ref(); let mut handler = hook(error); @@ -93,7 +81,7 @@ fn capture_handler(error: &(dyn Diagnostic + 'static)) -> Box { handler } -fn get_default_printer(_err: &(dyn Diagnostic + 'static)) -> Box { +fn get_default_printer(_err: &(dyn Diagnostic + 'static)) -> Box { let fancy = if let Ok(string) = std::env::var("NO_COLOR") { string == "0" } else if let Ok(string) = std::env::var("CLICOLOR") { @@ -102,15 +90,15 @@ fn get_default_printer(_err: &(dyn Diagnostic + 'static)) -> Box(&self) -> bool { + pub fn is(&self) -> bool { // Get `TypeId` of the type this function is instantiated with. let t = core::any::TypeId::of::(); @@ -122,18 +110,18 @@ impl dyn EyreHandler { } /// - pub fn downcast_ref(&self) -> Option<&T> { + pub fn downcast_ref(&self) -> Option<&T> { if self.is::() { - unsafe { Some(&*(self as *const dyn EyreHandler as *const T)) } + unsafe { Some(&*(self as *const dyn ReportHandler as *const T)) } } else { None } } /// - pub fn downcast_mut(&mut self) -> Option<&mut T> { + pub fn downcast_mut(&mut self) -> Option<&mut T> { if self.is::() { - unsafe { Some(&mut *(self as *mut dyn EyreHandler as *mut T)) } + unsafe { Some(&mut *(self as *mut dyn ReportHandler as *mut T)) } } else { None } @@ -141,7 +129,7 @@ impl dyn EyreHandler { } /// Error Report Handler trait for customizing `eyre::Report` -pub trait EyreHandler: core::any::Any + Send + Sync { +pub trait ReportHandler: core::any::Any + Send + Sync { /// Define the report format /// /// Used to override the report format of `eyre::Report` diff --git a/src/printer/graphical_printer.rs b/src/printer/graphical_printer.rs index 14f14f96..a029e28c 100644 --- a/src/printer/graphical_printer.rs +++ b/src/printer/graphical_printer.rs @@ -5,10 +5,10 @@ use owo_colors::{OwoColorize, Style}; use crate::chain::Chain; use crate::printer::theme::*; use crate::protocol::{Diagnostic, DiagnosticSnippet, Severity}; -use crate::{EyreHandler, SourceSpan, SpanContents}; +use crate::{ReportHandler, SourceSpan, SpanContents}; /** -A [DiagnosticReportPrinter] that displays a given [crate::DiagnosticReport] in a quasi-graphical way, using terminal colors, unicode drawing characters, and other such things. +A [ReportHandler] that displays a given [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`. @@ -19,18 +19,18 @@ 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())); +use miette::{GraphicalReportHandler, GraphicalTheme}; +miette::set_printer(GraphicalReportHandler::new_themed(GraphicalTheme::unicode_nocolor())); ``` */ #[derive(Debug, Clone)] -pub struct GraphicalReportPrinter { +pub struct GraphicalReportHandler { pub(crate) linkify_code: bool, pub(crate) theme: GraphicalTheme, } -impl GraphicalReportPrinter { - /// Create a new [GraphicalReportPrinter] with the default +impl GraphicalReportHandler { + /// Create a new [GraphicalReportHandler] with the default /// [GraphicalTheme]. This will use both unicode characters and colors. pub fn new() -> Self { Self { @@ -39,7 +39,7 @@ impl GraphicalReportPrinter { } } - ///Create a new [GraphicalReportPrinter] with a given [GraphicalTheme]. + ///Create a new [GraphicalReportHandler] with a given [GraphicalTheme]. pub fn new_themed(theme: GraphicalTheme) -> Self { Self { linkify_code: true, @@ -54,15 +54,15 @@ impl GraphicalReportPrinter { } } -impl Default for GraphicalReportPrinter { +impl Default for GraphicalReportHandler { fn default() -> Self { Self::new() } } -impl GraphicalReportPrinter { +impl GraphicalReportHandler { /// Render a [Diagnostic]. This function is mostly internal and meant to - /// be called by the toplevel [DiagnosticReportPrinter] handler, but is + /// be called by the toplevel [ReportHandler] handler, but is /// made public to make it easier (possible) to test in isolation from /// global state. pub fn render_report( @@ -515,7 +515,7 @@ impl GraphicalReportPrinter { } } -impl EyreHandler for GraphicalReportPrinter { +impl ReportHandler for GraphicalReportHandler { fn debug(&self, diagnostic: &(dyn Diagnostic), f: &mut fmt::Formatter<'_>) -> fmt::Result { if f.alternate() { return fmt::Debug::fmt(diagnostic, f); diff --git a/src/printer/narratable_printer.rs b/src/printer/narratable_printer.rs index e0a928ba..6603f350 100644 --- a/src/printer/narratable_printer.rs +++ b/src/printer/narratable_printer.rs @@ -2,33 +2,33 @@ use std::fmt; use crate::chain::Chain; use crate::protocol::{Diagnostic, DiagnosticSnippet, Severity}; -use crate::{EyreHandler, SourceSpan, SpanContents}; +use crate::{ReportHandler, SourceSpan, SpanContents}; /** -[DiagnosticReportPrinter] that renders plain text and avoids extraneous graphics. +[ReportHandler] that renders plain text and avoids extraneous graphics. It's optimized for screen readers and braille users, but is also used in any non-graphical environments, such as non-TTY output. */ #[derive(Debug, Clone)] -pub struct NarratableReportPrinter; +pub struct NarratableReportHandler; -impl NarratableReportPrinter { - /// Create a new [NarratableReportPrinter]. There are no customization +impl NarratableReportHandler { + /// Create a new [NarratableReportHandler]. There are no customization /// options. pub fn new() -> Self { Self } } -impl Default for NarratableReportPrinter { +impl Default for NarratableReportHandler { fn default() -> Self { Self::new() } } -impl NarratableReportPrinter { +impl NarratableReportHandler { /// Render a [Diagnostic]. This function is mostly internal and meant to - /// be called by the toplevel [DiagnosticReportPrinter] handler, but is + /// be called by the toplevel [ReportHandler] handler, but is /// made public to make it easier (possible) to test in isolation from /// global state. pub fn render_report( @@ -194,7 +194,7 @@ impl NarratableReportPrinter { } } -impl EyreHandler for NarratableReportPrinter { +impl ReportHandler for NarratableReportHandler { fn debug(&self, diagnostic: &(dyn Diagnostic), f: &mut fmt::Formatter<'_>) -> fmt::Result { if f.alternate() { return fmt::Debug::fmt(diagnostic, f); diff --git a/src/printer/theme.rs b/src/printer/theme.rs index 6f2b4644..bd744f0e 100644 --- a/src/printer/theme.rs +++ b/src/printer/theme.rs @@ -2,7 +2,7 @@ use atty::Stream; use owo_colors::Style; /** -Theme used by [crate::GraphicalReportPrinter] to render fancy [crate::Diagnostic] reports. +Theme used by [crate::GraphicalReportHandler] 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. @@ -47,8 +47,8 @@ impl GraphicalTheme { /// 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]! + /// [crate::NarratableReportHandler], or write your own + /// [crate::ReportHandler]! pub fn none() -> Self { Self { characters: ThemeCharacters::ascii(), @@ -68,7 +68,7 @@ impl Default for GraphicalTheme { } /** -Styles for various parts of graphical rendering for the [crate::GraphicalReportPrinter]. +Styles for various parts of graphical rendering for the [crate::GraphicalReportHandler]. */ #[derive(Debug, Clone)] pub struct ThemeStyles { @@ -150,7 +150,7 @@ impl ThemeStyles { // Most of these characters were taken from // https://github.com/zesterer/ariadne/blob/e3cb394cb56ecda116a0a1caecd385a49e7f6662/src/draw.rs -/// Characters to be used when drawing when using [crate::GraphicalReportPrinter]. +/// Characters to be used when drawing when using [crate::GraphicalReportHandler]. #[allow(missing_docs)] #[derive(Debug, Clone, Eq, PartialEq)] pub struct ThemeCharacters { diff --git a/src/protocol.rs b/src/protocol.rs index ed222aa3..9c5a132e 100644 --- a/src/protocol.rs +++ b/src/protocol.rs @@ -4,12 +4,16 @@ that you can implement to get access to miette's (and related library's) full reporting and such features. */ -use std::{fmt::{self, Display}, fs, panic::Location}; +use std::{ + fmt::{self, Display}, + fs, + panic::Location, +}; use crate::{MietteError, Report}; /** -Adds rich metadata to your Error that can be used by [DiagnosticReportPrinter] to print +Adds rich metadata to your Error that can be used by [ReportHandler] to print really nice and human-friendly error messages. */ pub trait Diagnostic: std::error::Error { @@ -22,7 +26,7 @@ pub trait Diagnostic: std::error::Error { None } - /// Diagnostic severity. This may be used by [DiagnosticReportPrinter]s to change the + /// Diagnostic severity. This may be used by [ReportHandler]s to change the /// display format of this diagnostic. /// /// If `None`, reporters should treat this as [Severity::Error] @@ -135,7 +139,7 @@ impl From> for Box = Result; /** -[Diagnostic] severity. Intended to be used by [DiagnosticReportPrinter]s to change the +[Diagnostic] severity. Intended to be used by [ReportHandler]s to change the way different Diagnostics are displayed. */ #[derive(Copy, Clone, Debug, Eq, PartialEq)] diff --git a/tests/narrated.rs b/tests/narrated.rs index b3729696..625a2f88 100644 --- a/tests/narrated.rs +++ b/tests/narrated.rs @@ -1,6 +1,6 @@ use miette::{ - Diagnostic, Report, GraphicalReportPrinter, GraphicalTheme, MietteError, NamedSource, - NarratableReportPrinter, SourceSpan, + Diagnostic, GraphicalReportHandler, GraphicalTheme, MietteError, NamedSource, + NarratableReportHandler, Report, SourceSpan, }; use thiserror::Error; @@ -8,11 +8,11 @@ fn fmt_report(diag: Report) -> String { let mut out = String::new(); // Mostly for dev purposes. if std::env::var("STYLE").is_ok() { - GraphicalReportPrinter::new_themed(GraphicalTheme::unicode()) + GraphicalReportHandler::new_themed(GraphicalTheme::unicode()) .render_report(&mut out, diag.as_ref()) .unwrap(); } else { - NarratableReportPrinter + NarratableReportHandler .render_report(&mut out, diag.as_ref()) .unwrap(); }; diff --git a/tests/printer.rs b/tests/printer.rs index 81b16853..b485c5cf 100644 --- a/tests/printer.rs +++ b/tests/printer.rs @@ -1,6 +1,6 @@ use miette::{ - Diagnostic, Report, GraphicalReportPrinter, GraphicalTheme, MietteError, NamedSource, - NarratableReportPrinter, SourceSpan, + Diagnostic, GraphicalReportHandler, GraphicalTheme, MietteError, NamedSource, + NarratableReportHandler, Report, SourceSpan, }; use thiserror::Error; @@ -8,15 +8,15 @@ fn fmt_report(diag: Report) -> String { let mut out = String::new(); // Mostly for dev purposes. if std::env::var("STYLE").is_ok() { - GraphicalReportPrinter::new_themed(GraphicalTheme::unicode()) + GraphicalReportHandler::new_themed(GraphicalTheme::unicode()) .render_report(&mut out, diag.as_ref()) .unwrap(); } else if std::env::var("NARRATED").is_ok() { - NarratableReportPrinter + NarratableReportHandler .render_report(&mut out, diag.as_ref()) .unwrap(); } else { - GraphicalReportPrinter::new_themed(GraphicalTheme::unicode_nocolor()) + GraphicalReportHandler::new_themed(GraphicalTheme::unicode_nocolor()) .render_report(&mut out, diag.as_ref()) .unwrap(); }; @@ -481,7 +481,7 @@ fn disable_url_links() -> Result<(), MietteError> { struct MyBad; let err = MyBad; let mut out = String::new(); - GraphicalReportPrinter::new_themed(GraphicalTheme::unicode_nocolor()) + GraphicalReportHandler::new_themed(GraphicalTheme::unicode_nocolor()) .without_code_linking() .render_report(&mut out, &err) .unwrap(); diff --git a/tests/test_boxed.rs b/tests/test_boxed.rs index 1d3c45b7..af16db70 100644 --- a/tests/test_boxed.rs +++ b/tests/test_boxed.rs @@ -66,6 +66,11 @@ fn test_boxed_sources() { assert_eq!("outer", error.source().unwrap().to_string()); assert_eq!( "oh no!", - error.source().expect("outer").source().expect("inner").to_string() + error + .source() + .expect("outer") + .source() + .expect("inner") + .to_string() ); } diff --git a/tests/test_fmt.rs b/tests/test_fmt.rs index 9bfc215a..8f182165 100644 --- a/tests/test_fmt.rs +++ b/tests/test_fmt.rs @@ -80,7 +80,7 @@ fn test_altdisplay() { #[test] #[ignore = "not really gonna work with the current printers"] -#[cfg_attr(any(backtrace, track_caller), ignore)] +#[cfg_attr(track_caller, ignore)] fn test_debug() { assert_eq!(EXPECTED_DEBUG_F, format!("{:?}", f().unwrap_err())); assert_eq!(EXPECTED_DEBUG_G, format!("{:?}", g().unwrap_err())); diff --git a/tests/test_location.rs b/tests/test_location.rs index 810db4d6..91055d7d 100644 --- a/tests/test_location.rs +++ b/tests/test_location.rs @@ -16,7 +16,7 @@ impl LocationHandler { } } -impl miette::EyreHandler for LocationHandler { +impl miette::ReportHandler for LocationHandler { fn debug( &self, _error: &(dyn Diagnostic + 'static),