From a03bfe2e1b162424f50dba68726c0cab3d0cd520 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kat=20March=C3=A1n?= Date: Thu, 5 May 2022 08:56:27 -0700 Subject: [PATCH] docs: document new diagnostic_source feature --- README.md | 198 ++++------------------------------------------------- src/lib.rs | 74 ++++++++++++++------ 2 files changed, 66 insertions(+), 206 deletions(-) diff --git a/README.md b/README.md index 0f27314..eb6869c 100644 --- a/README.md +++ b/README.md @@ -369,201 +369,29 @@ pub struct MyErrorType { // They'll be rendered sequentially. #[label("This is bad")] snip2: (usize, usize), // `(usize, usize)` is `Into`! + + // Snippets can be optional, by using Option: + #[label("some text")] + snip3: Option, + + // with or without label text + #[label] + snip4: Option, } ``` -#### ... help text - +##### ... help text `miette` provides two facilities for supplying help text for your errors: -The first is the `#[help()]` format attribute that applies to structs or enum variants: - -```rust -#[derive(Debug, Diagnostic, Error)] -#[error("welp")] -#[diagnostic(help("try doing this instead"))] -struct Foo; -``` - -The other is by programmatically supplying the help text as a field to your -diagnostic: - -```rust -#[derive(Debug, Diagnostic, Error)] -#[error("welp")] -#[diagnostic()] -struct Foo { - #[help] - advice: Option -} - -let err = Foo { advice: Some("try doing this instead".to_string()) }; -``` - -#### ... multiple related errors - -`miette` supports collecting multiple errors into a single diagnostic, and -printing them all together nicely. - -To do so, use the `#[related]` tag on any `IntoIter` field in your -`Diagnostic` type: - -```rust -use miette::Diagnostic; -use thiserror::Error; - -#[derive(Debug, Error, Diagnostic)] -#[error("oops")] -struct MyError { - #[related] - others: Vec, -} -``` - -#### ... delayed source code - -Sometimes it makes sense to add source code to the error message later. One -option is to use [`with_source_code()`](Report::with_source_code) method for -that: - -```rust -use miette::{Diagnostic, SourceSpan}; -use thiserror::Error; - -#[derive(Diagnostic, Debug, Error)] -#[error("oops")] -#[diagnostic()] -pub struct MyErrorType { - // Note: label but no source code - #[label] - err_span: SourceSpan, -} - -fn do_something() -> miette::Result<()> { - // This function emits actual error with label - return Err(MyErrorType { - err_span: (7..11).into(), - })?; -} - -fn main() -> miette::Result<()> { - do_something().map_err(|error| { - // And this code provides the source code for inner error - error.with_source_code(String::from("source code")) - }) -} -``` - -Also source code can be provided by a wrapper type. This is especially -useful in combination with `related`, when multiple errors should be emitted -at the same time: - -```rust -use miette::{Diagnostic, Report, SourceSpan}; -use thiserror::Error; - -#[derive(Diagnostic, Debug, Error)] -#[error("oops")] -#[diagnostic()] -pub struct InnerError { - // Note: label but no source code - #[label] - err_span: SourceSpan, -} - -#[derive(Diagnostic, Debug, Error)] -#[error("oops: multiple errors")] -#[diagnostic()] -pub struct MultiError { - // Note source code by no labels - #[source_code] - source_code: String, - // The source code above is used for these errors - #[related] - related: Vec, -} - -fn do_something() -> Result<(), Vec> { - Err(vec![ - InnerError { - err_span: (0..6).into(), - }, - InnerError { - err_span: (7..11).into(), - }, - ]) -} - -fn main() -> miette::Result<()> { - do_something().map_err(|err_list| MultiError { - source_code: "source code".into(), - related: err_list, - })?; - Ok(()) -} -``` - -#### ... handler options - -[`MietteHandler`] is the default handler, and is very customizable. In most -cases, you can simply use [`MietteHandlerOpts`] to tweak its behavior -instead of falling back to your own custom handler. - -Usage is like so: - -```rust -miette::set_hook(Box::new(|_| { - Box::new( - miette::MietteHandlerOpts::new() - .terminal_links(true) - .unicode(false) - .context_lines(3) - .tab_width(4) - .build(), - ) -})) - -``` - -See the docs for [`MietteHandlerOpts`] for more details on what you can -customize! - -### Acknowledgements - -`miette` was not developed in a void. It owes enormous credit to various -other projects and their authors: - -- [`anyhow`](http://crates.io/crates/anyhow) and [`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 `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 - `miette`'s derive macro. -- `rustc` and [@estebank](https://github.com/estebank) for their - state-of-the-art work in compiler diagnostics. -- [`ariadne`](https://crates.io/crates/ariadne) for pushing forward how - _pretty_ these diagnostics can really look! - -### License - -`miette` is released to the Rust community under the -[Apache license 2.0](./LICENSE). - -It also includes code taken from [`eyre`](https://github.com/yaahc/eyre), -and some from [`thiserror`](https://github.com/dtolnay/thiserror), also under -the Apache License. Some code is taken from -[`ariadne`](https://github.com/zesterer/ariadne), which is MIT licensed. - [`miette!`]: https://docs.rs/miette/latest/miette/macro.miette.html [`std::error::Error`]: https://doc.rust-lang.org/nightly/std/error/trait.Error.html -[`Diagnostic`]: https://docs.rs/miette/latest/miette/trait.Diagnostic.html +[`std::error::Error::source`]: https://doc.rust-lang.org/nightly/std/error/trait.Error.html#method.source +[`Diagnostic`]: https://docs.rs/miette/latest/miette/struct.Diagnostic.html [`IntoDiagnostic`]: https://docs.rs/miette/latest/miette/trait.IntoDiagnostic.html [`MietteHandlerOpts`]: https://docs.rs/miette/latest/miette/struct.MietteHandlerOpts.html [`MietteHandler`]: https://docs.rs/miette/latest/miette/struct.MietteHandler.html [`Report`]: https://docs.rs/miette/latest/miette/struct.Report.html -[`ReportHandler`]: https://docs.rs/miette/latest/miette/trait.ReportHandler.html +[`ReportHandler`]: https://docs.rs/miette/latest/miette/struct.ReportHandler.html [`Result`]: https://docs.rs/miette/latest/miette/type.Result.html -[`SourceCode`]: https://docs.rs/miette/latest/miette/trait.SourceCode.html +[`SourceCode`]: https://docs.rs/miette/latest/miette/struct.SourceCode.html [`SourceSpan`]: https://docs.rs/miette/latest/miette/struct.SourceSpan.html diff --git a/src/lib.rs b/src/lib.rs index e397712..a79700a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -395,8 +395,8 @@ //! struct Foo; //! ``` //! -//! The other is by programmatically supplying the help text as a field to your -//! diagnostic: +//! The other is by programmatically supplying the help text as a field to +//! your diagnostic: //! //! ```rust //! use miette::Diagnostic; @@ -437,9 +437,9 @@ //! //! ### ... delayed source code //! -//! Sometimes it makes sense to add source code to the error message later. One -//! option is to use [`with_source_code()`](Report::with_source_code) method for -//! that: +//! Sometimes it makes sense to add source code to the error message later. +//! One option is to use [`with_source_code()`](Report::with_source_code) +//! method for that: //! //! ```rust,no_run //! use miette::{Diagnostic, SourceSpan}; @@ -470,8 +470,8 @@ //! ``` //! //! Also source code can be provided by a wrapper type. This is especially -//! useful in combination with `related`, when multiple errors should be emitted -//! at the same time: +//! useful in combination with `related`, when multiple errors should be +//! emitted at the same time: //! //! ```rust,no_run //! use miette::{Diagnostic, Report, SourceSpan}; @@ -518,10 +518,41 @@ //! } //! ``` //! +//! ### ... Diagnostic-based error sources. +//! +//! When one uses the `#[source]` attribute on a field, that usually comes +//! from `thiserror`, and implements a method for +//! [`std::error::Error::source`]. This works in many cases, but it's lossy: +//! if the source of the diagnostic is a diagnostic itself, the source will +//! simply be treated as an `std::error::Error`. +//! +//! While this has no effect on the existing _reporters_, since they don't use +//! that information right now, APIs who might want this information will have +//! no access to it. +//! +//! If it's important for you for this information to be available to users, +//! you can use `#[diagnostic_source]` alongside `#[source]`. Not that you +//! will likely want to use _both_: +//! +//! ```rust +//! use miette::Diagnostic; +//! use thiserror::Error; +//! +//! #[derive(Debug, Diagnostic, Error)] +//! struct MyError { +//! #[source] +//! #[diagnostic_source] +//! the_cause: OtherError, +//! } +//! +//! #[derive(Debug, Diagnostic, Error)] +//! struct OtherError; +//! ``` +//! //! ### ... handler options //! -//! [`MietteHandler`] is the default handler, and is very customizable. In most -//! cases, you can simply use [`MietteHandlerOpts`] to tweak its behavior +//! [`MietteHandler`] is the default handler, and is very customizable. In +//! most cases, you can simply use [`MietteHandlerOpts`] to tweak its behavior //! instead of falling back to your own custom handler. //! //! Usage is like so: @@ -549,14 +580,15 @@ //! `miette` was not developed in a void. It owes enormous credit to various //! other projects and their authors: //! -//! - [`anyhow`](http://crates.io/crates/anyhow) and [`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 `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 -//! `miette`'s derive macro. +//! - [`anyhow`](http://crates.io/crates/anyhow) and +//! [`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 `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 `miette`'s derive macro. //! - `rustc` and [@estebank](https://github.com/estebank) for their //! state-of-the-art work in compiler diagnostics. //! - [`ariadne`](https://crates.io/crates/ariadne) for pushing forward how @@ -564,12 +596,12 @@ //! //! ## License //! -//! `miette` is released to the Rust community under the -//! [Apache license 2.0](./LICENSE). +//! `miette` is released to the Rust community under the [Apache license +//! 2.0](./LICENSE). //! //! It also includes code taken from [`eyre`](https://github.com/yaahc/eyre), -//! and some from [`thiserror`](https://github.com/dtolnay/thiserror), also under -//! the Apache License. Some code is taken from +//! and some from [`thiserror`](https://github.com/dtolnay/thiserror), also +//! under the Apache License. Some code is taken from //! [`ariadne`](https://github.com/zesterer/ariadne), which is MIT licensed. pub use miette_derive::*;