mirror of https://github.com/zkat/miette.git
Fixed/formatted all intradoc links. Various other small doc fixes/typography/etc.
This commit is contained in:
parent
50bcec909a
commit
ccc97310fa
103
README.md
103
README.md
|
|
@ -24,8 +24,8 @@ but it's definitely a bug and should be reported.
|
||||||
diagnostic error code: ruget::api::bad_json
|
diagnostic error code: ruget::api::bad_json
|
||||||
" />
|
" />
|
||||||
|
|
||||||
**NOTE: You must enable the `"fancy"` crate feature to get fancy report output
|
> **NOTE: You must enable the `"fancy"` crate feature to get fancy report
|
||||||
like in the screenshots here.** You should only do this in your toplevel
|
output like in the screenshots above.** You should only do this in your toplevel
|
||||||
crate, as the fancy feature pulls in a number of dependencies that libraries
|
crate, as the fancy feature pulls in a number of dependencies that libraries
|
||||||
and such might not want.
|
and such might not want.
|
||||||
|
|
||||||
|
|
@ -49,22 +49,25 @@ and such might not want.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- Generic [Diagnostic] protocol, compatible (and dependent on) `std::error::Error`.
|
- Generic [`Diagnostic`] protocol, compatible (and dependent on) `std::error::Error`.
|
||||||
- Unique error codes on every [Diagnostic].
|
- Unique error codes on every [`Diagnostic`].
|
||||||
- Custom links to get more details on error codes.
|
- Custom links to get more details on error codes.
|
||||||
- Super handy derive macro for defining diagnostic metadata.
|
- Super handy derive macro for defining diagnostic metadata.
|
||||||
- [`anyhow`](https://docs.rs/anyhow)/[`eyre`](https://docs.rs/eyre)-compatible error wrapper type, [Report],
|
- [`anyhow`](https://docs.rs/anyhow)/[`eyre`](https://docs.rs/eyre) error
|
||||||
which can be returned from `main`.
|
wrapper type, [`Report`], which can be returned from `main()`.
|
||||||
- Generic support for arbitrary [SourceCode]s for snippet data, with default support for `String`s included.
|
- Generic support for arbitrary [`SourceCode`]s for snippet data, with default
|
||||||
|
support for `String`s included.
|
||||||
|
|
||||||
The `miette` crate also comes bundled with a default [ReportHandler] 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
|
- Fancy graphical [diagnostic output](#about), using ANSI/Unicode text
|
||||||
- single- and multi-line highlighting support
|
- single- and multi-line highlighting support
|
||||||
- Screen reader/braille support, gated on [`NO_COLOR`](http://no-color.org/), and other heuristics.
|
- Screen reader/braille support, gated on [`NO_COLOR`](http://no-color.org/),
|
||||||
|
and other heuristics.
|
||||||
- Fully customizable graphical theming (or overriding the printers entirely).
|
- Fully customizable graphical theming (or overriding the printers entirely).
|
||||||
- Cause chain printing
|
- Cause chain printing
|
||||||
- Turns diagnostic codes into links in [supported terminals](https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda).
|
- Turns diagnostic codes into links in [supported
|
||||||
|
terminals](https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda).
|
||||||
|
|
||||||
## Installing
|
## Installing
|
||||||
|
|
||||||
|
|
@ -84,7 +87,7 @@ $ cargo add miette --features fancy
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
/*
|
/*
|
||||||
You can derive a Diagnostic from any `std::error::Error` type.
|
You can derive a `Diagnostic` from any `std::error::Error` type.
|
||||||
|
|
||||||
`thiserror` is a great way to define them, and plays nicely with `miette`!
|
`thiserror` is a great way to define them, and plays nicely with `miette`!
|
||||||
*/
|
*/
|
||||||
|
|
@ -111,9 +114,9 @@ struct MyBad {
|
||||||
/*
|
/*
|
||||||
Now let's define a function!
|
Now let's define a function!
|
||||||
|
|
||||||
Use this Result type (or its expanded version) as the return type
|
Use this `Result` type (or its expanded version) as the return type
|
||||||
throughout your app (but NOT your libraries! Those should always return concrete
|
throughout your app (but NOT your libraries! Those should always return
|
||||||
types!).
|
concrete types!).
|
||||||
*/
|
*/
|
||||||
use miette::{Result, NamedSource};
|
use miette::{Result, NamedSource};
|
||||||
fn this_fails() -> Result<()> {
|
fn this_fails() -> Result<()> {
|
||||||
|
|
@ -131,10 +134,11 @@ fn this_fails() -> Result<()> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Now to get everything printed nicely, just return a Result<()>
|
Now to get everything printed nicely, just return a `Result<()>`
|
||||||
and you're all set!
|
and you're all set!
|
||||||
|
|
||||||
Note: You can swap out the default reporter for a custom one using `miette::set_hook()`
|
Note: You can swap out the default reporter for a custom one using
|
||||||
|
`miette::set_hook()`
|
||||||
*/
|
*/
|
||||||
fn pretend_this_is_main() -> Result<()> {
|
fn pretend_this_is_main() -> Result<()> {
|
||||||
// kaboom~
|
// kaboom~
|
||||||
|
|
@ -167,12 +171,13 @@ For more details, see https://docs.rs/nu-parser/0.1.0/nu-parser/enum.ParseError.
|
||||||
|
|
||||||
`miette` is _fully compatible_ with library usage. Consumers who don't know
|
`miette` is _fully compatible_ with library usage. Consumers who don't know
|
||||||
about, or don't want, `miette` features can safely use its error types as
|
about, or don't want, `miette` features can safely use its error types as
|
||||||
regular [std::error::Error].
|
regular [`std::error::Error`].
|
||||||
|
|
||||||
We highly recommend using something like [`thiserror`](https://docs.rs/thiserror) to define unique error types and error wrappers for your library.
|
We highly recommend using something like [`thiserror`](https://docs.rs/thiserror)
|
||||||
|
to define unique error types and error wrappers for your library.
|
||||||
|
|
||||||
While `miette` integrates smoothly with `thiserror`, it is _not required_. If
|
While `miette` integrates smoothly with `thiserror`, it is _not required_. If
|
||||||
you don't want to use the [Diagnostic] derive macro, you can implement the
|
you don't want to use the [`Diagnostic`] derive macro, you can implement the
|
||||||
trait directly, just like with `std::error::Error`.
|
trait directly, just like with `std::error::Error`.
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
|
|
@ -194,7 +199,7 @@ pub enum MyLibError {
|
||||||
|
|
||||||
Then, return this error type from all your fallible public APIs. It's a best
|
Then, return this error type from all your fallible public APIs. It's a best
|
||||||
practice to wrap any "external" error types in your error `enum` instead of
|
practice to wrap any "external" error types in your error `enum` instead of
|
||||||
using something like [Report] in a library.
|
using something like [`Report`] in a library.
|
||||||
|
|
||||||
### ... in application code
|
### ... in application code
|
||||||
|
|
||||||
|
|
@ -202,10 +207,10 @@ 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
|
always need or care to define dedicated error wrappers for errors coming from
|
||||||
external libraries and tools.
|
external libraries and tools.
|
||||||
|
|
||||||
For this situation, `miette` includes two tools: [Report] and
|
For this situation, `miette` includes two tools: [`Report`] and
|
||||||
[IntoDiagnostic]. They work in tandem to make it easy to convert regular
|
[`IntoDiagnostic`]. They work in tandem to make it easy to convert regular
|
||||||
`std::error::Error`s into [Diagnostic]s. Additionally, there's a
|
`std::error::Error`s into [`Diagnostic`]s. Additionally, there's a
|
||||||
[Result] type alias that you can use to be more terse.
|
[`Result`] type alias that you can use to be more terse.
|
||||||
|
|
||||||
When dealing with non-`Diagnostic` types, you'll want to `.into_diagnostic()`
|
When dealing with non-`Diagnostic` types, you'll want to `.into_diagnostic()`
|
||||||
them:
|
them:
|
||||||
|
|
@ -237,11 +242,11 @@ pub fn some_tool() -> Result<Version> {
|
||||||
### ... in `main()`
|
### ... in `main()`
|
||||||
|
|
||||||
`main()` is just like any other part of your application-internal code. Use
|
`main()` is just like any other part of your application-internal code. Use
|
||||||
`Result` as your return value, and it will pretty-print your
|
`Result` as your return value, and it will pretty-print your diagnostics
|
||||||
diagnostics automatically.
|
automatically.
|
||||||
|
|
||||||
**NOTE: You must enable the `"fancy"` crate feature to get fancy report output
|
> **NOTE:** You must enable the `"fancy"` crate feature to get fancy report
|
||||||
like in the screenshots here.** You should only do this in your toplevel
|
output like in the screenshots here.** You should only do this in your toplevel
|
||||||
crate, as the fancy feature pulls in a number of dependencies that libraries
|
crate, as the fancy feature pulls in a number of dependencies that libraries
|
||||||
and such might not want.
|
and such might not want.
|
||||||
|
|
||||||
|
|
@ -297,10 +302,10 @@ struct MyErr;
|
||||||
```
|
```
|
||||||
|
|
||||||
Additionally, if you're developing a library and your error type is exported
|
Additionally, if you're developing a library and your error type is exported
|
||||||
from your crate's top level, you can use a special `url(docsrs)` option
|
from your crate's top level, you can use a special `url(docsrs)` option instead
|
||||||
instead of manually constructing the URL. This will automatically create a
|
of manually constructing the URL. This will automatically create a link to this
|
||||||
link to this diagnostic on `docs.rs`, so folks can just go straight to
|
diagnostic on `docs.rs`, so folks can just go straight to your (very high
|
||||||
your (very high quality and detailed!) documentation on this diagnostic:
|
quality and detailed!) documentation on this diagnostic:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
use miette::Diagnostic;
|
use miette::Diagnostic;
|
||||||
|
|
@ -323,8 +328,8 @@ includes facilities for adding error spans/annotations/labels to your output.
|
||||||
This can be very useful when an error is syntax-related, but you can even use
|
This can be very useful when an error is syntax-related, but you can even use
|
||||||
it to print out sections of your own source code!
|
it to print out sections of your own source code!
|
||||||
|
|
||||||
To achieve this, `miette` defines its own lightweight [SourceSpan] type. This
|
To achieve this, `miette` defines its own lightweight [`SourceSpan`] type. This
|
||||||
is a basic byte-offset and length into an associated [SourceCode] and, along
|
is a basic byte-offset and length into an associated [`SourceCode`] and, along
|
||||||
with the latter, gives `miette` all the information it needs to pretty-print
|
with the latter, gives `miette` all the information it needs to pretty-print
|
||||||
some snippets! You can also use your own `Into<SourceSpan>` types as label
|
some snippets! You can also use your own `Into<SourceSpan>` types as label
|
||||||
spans.
|
spans.
|
||||||
|
|
@ -352,7 +357,7 @@ pub struct MyErrorType {
|
||||||
// You can add as many labels as you want.
|
// You can add as many labels as you want.
|
||||||
// They'll be rendered sequentially.
|
// They'll be rendered sequentially.
|
||||||
#[label("This is bad")]
|
#[label("This is bad")]
|
||||||
snip2: (usize, usize), // (usize, usize) is Into<SourceSpan>!
|
snip2: (usize, usize), // `(usize, usize)` is `Into<SourceSpan>`!
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -361,8 +366,8 @@ pub struct MyErrorType {
|
||||||
`miette` supports collecting multiple errors into a single diagnostic, and
|
`miette` supports collecting multiple errors into a single diagnostic, and
|
||||||
printing them all together nicely.
|
printing them all together nicely.
|
||||||
|
|
||||||
To do so, use the `#[related]` tag on any `IntoIter` field in your
|
To do so, use the `#[related]` tag on any `IntoIter` field in your `Diagnostic`
|
||||||
`Diagnostic` type:
|
type:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
use miette::Diagnostic;
|
use miette::Diagnostic;
|
||||||
|
|
@ -379,7 +384,7 @@ struct MyError {
|
||||||
### ... delayed source code
|
### ... delayed source code
|
||||||
|
|
||||||
Sometimes it makes sense to add source code to the error message later. One
|
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
|
option is to use [`with_source_code()`](Report::with_source_code) method for
|
||||||
that:
|
that:
|
||||||
|
|
||||||
```rust,no_run
|
```rust,no_run
|
||||||
|
|
@ -458,8 +463,8 @@ fn main() -> miette::Result<()> {
|
||||||
|
|
||||||
### ... handler options
|
### ... handler options
|
||||||
|
|
||||||
[MietteHandler] is the default handler, and is very customizable. In most
|
[`MietteHandler`] is the default handler, and is very customizable. In most
|
||||||
cases, you can simply use [MietteHandlerOpts] to tweak its behavior instead
|
cases, you can simply use [`MietteHandlerOpts`] to tweak its behavior instead
|
||||||
of falling back to your own custom handler.
|
of falling back to your own custom handler.
|
||||||
|
|
||||||
Usage is like so:
|
Usage is like so:
|
||||||
|
|
@ -477,29 +482,31 @@ miette::set_hook(Box::new(|_| {
|
||||||
# .unwrap()
|
# .unwrap()
|
||||||
```
|
```
|
||||||
|
|
||||||
See the docs for [MietteHandlerOpts] for more details on what you can customize!
|
See the docs for [`MietteHandlerOpts`] for more details on what you can
|
||||||
|
customize!
|
||||||
|
|
||||||
## Acknowledgements
|
## Acknowledgements
|
||||||
|
|
||||||
`miette` was not developed in a void. It owes enormous credit to various other projects and their authors:
|
`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
|
- [`anyhow`](http://crates.io/crates/anyhow) and
|
||||||
[`color-eyre`](https://crates.io/crates/color-eyre): these two enormously
|
[`color-eyre`](https://crates.io/crates/color-eyre): these two enormously
|
||||||
influential error handling libraries have pushed forward the experience of
|
influential error handling libraries have pushed forward the experience of
|
||||||
application-level error handling and error reporting. `miette`'s
|
application-level error handling and error reporting. `miette`'s `Report`
|
||||||
`Report` type is an attempt at a very very rough version of their
|
type is an attempt at a very very rough version of their `Report` types.
|
||||||
`Report` types.
|
|
||||||
- [`thiserror`](https://crates.io/crates/thiserror) for setting the standard
|
- [`thiserror`](https://crates.io/crates/thiserror) for setting the standard
|
||||||
for library-level error definitions, and for being the inspiration behind
|
for library-level error definitions, and for being the inspiration behind
|
||||||
`miette`'s derive macro.
|
`miette`'s derive macro.
|
||||||
- `rustc` and [@estebank](https://github.com/estebank) for their state-of-the-art
|
- `rustc` and [@estebank](https://github.com/estebank) for their
|
||||||
work in compiler diagnostics.
|
state-of-the-art work in compiler diagnostics.
|
||||||
- [`ariadne`](https://crates.io/crates/ariadne) for pushing forward how
|
- [`ariadne`](https://crates.io/crates/ariadne) for pushing forward how
|
||||||
_pretty_ these diagnostics can really look!
|
_pretty_ these diagnostics can really look!
|
||||||
|
|
||||||
## License
|
## 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),
|
It also includes code taken from [`eyre`](https://github.com/yaahc/eyre),
|
||||||
and some from [`thiserror`](https://github.com/dtolnay/thiserror), also under
|
and some from [`thiserror`](https://github.com/dtolnay/thiserror), also under
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,8 @@ pub(crate) fn gen_unused_pat(fields: &syn::Fields) -> TokenStream {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Goes in the slot `let Self #pat = self;` or `match self { Self #pat => ... }`.
|
/// Goes in the slot `let Self #pat = self;` or `match self { Self #pat => ...
|
||||||
|
/// }`.
|
||||||
fn gen_fields_pat(fields: &syn::Fields) -> TokenStream {
|
fn gen_fields_pat(fields: &syn::Fields) -> TokenStream {
|
||||||
let member_idents = fields.iter().enumerate().map(|(i, field)| {
|
let member_idents = fields.iter().enumerate().map(|(i, field)| {
|
||||||
field
|
field
|
||||||
|
|
@ -103,8 +104,9 @@ fn gen_fields_pat(fields: &syn::Fields) -> TokenStream {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The returned tokens go in the slot `let Self #pat = self;` or `match self { Self #pat => ... }`.
|
/// The returned tokens go in the slot `let Self #pat = self;` or `match self {
|
||||||
/// The members can be passed to `Display::expand_shorthand[_cloned]`.
|
/// Self #pat => ... }`. The members can be passed to
|
||||||
|
/// `Display::expand_shorthand[_cloned]`.
|
||||||
pub(crate) fn display_pat_members(fields: &syn::Fields) -> (TokenStream, HashSet<syn::Member>) {
|
pub(crate) fn display_pat_members(fields: &syn::Fields) -> (TokenStream, HashSet<syn::Member>) {
|
||||||
let pat = gen_fields_pat(fields);
|
let pat = gen_fields_pat(fields);
|
||||||
let members: HashSet<syn::Member> = fields
|
let members: HashSet<syn::Member> = fields
|
||||||
|
|
@ -125,7 +127,8 @@ pub(crate) fn display_pat_members(fields: &syn::Fields) -> (TokenStream, HashSet
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display {
|
impl Display {
|
||||||
/// Returns `(fmt, args)` which must be passed to some kind of format macro without tokens in between, i.e. `format!(#fmt #args)`.
|
/// Returns `(fmt, args)` which must be passed to some kind of format macro
|
||||||
|
/// without tokens in between, i.e. `format!(#fmt #args)`.
|
||||||
pub(crate) fn expand_shorthand_cloned(
|
pub(crate) fn expand_shorthand_cloned(
|
||||||
&self,
|
&self,
|
||||||
members: &HashSet<syn::Member>,
|
members: &HashSet<syn::Member>,
|
||||||
|
|
|
||||||
12
src/error.rs
12
src/error.rs
|
|
@ -9,13 +9,14 @@ Error enum for miette. Used by certain operations in the protocol.
|
||||||
*/
|
*/
|
||||||
#[derive(Debug, Diagnostic, Error)]
|
#[derive(Debug, Diagnostic, Error)]
|
||||||
pub enum MietteError {
|
pub enum MietteError {
|
||||||
/// Wrapper around [std::io::Error]. This is returned when something went
|
/// Wrapper around [`std::io::Error`]. This is returned when something went
|
||||||
/// wrong while reading a [crate::Source].
|
/// wrong while reading a [`SourceCode`](crate::SourceCode).
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
#[diagnostic(code(miette::io_error), url(docsrs))]
|
#[diagnostic(code(miette::io_error), url(docsrs))]
|
||||||
IoError(#[from] io::Error),
|
IoError(#[from] io::Error),
|
||||||
|
|
||||||
/// Returned when a [crate::SourceSpan] extends beyond the bounds of a given [crate::Source].
|
/// Returned when a [`SourceSpan`](crate::SourceSpan) extends beyond the
|
||||||
|
/// bounds of a given [`SourceCode`](crate::SourceCode).
|
||||||
#[error("The given offset is outside the bounds of its Source")]
|
#[error("The given offset is outside the bounds of its Source")]
|
||||||
#[diagnostic(
|
#[diagnostic(
|
||||||
code(miette::span_out_of_bounds),
|
code(miette::span_out_of_bounds),
|
||||||
|
|
@ -24,8 +25,9 @@ pub enum MietteError {
|
||||||
)]
|
)]
|
||||||
OutOfBounds,
|
OutOfBounds,
|
||||||
|
|
||||||
/// Returned when installing a [crate::ReportHandler] failed.
|
/// Returned when installing a [`ReportHandler`](crate::ReportHandler)
|
||||||
/// Typically, this will be because [crate::set_printer] was called twice.
|
/// failed. Typically, this will be because [`set_hook`](crate::set_hook)
|
||||||
|
/// was called twice.
|
||||||
#[error("Failed to install ReportHandler")]
|
#[error("Failed to install ReportHandler")]
|
||||||
#[diagnostic(code(miette::set_printer_failed), url(docsrs))]
|
#[diagnostic(code(miette::set_printer_failed), url(docsrs))]
|
||||||
SetPrinterFailure,
|
SetPrinterFailure,
|
||||||
|
|
|
||||||
|
|
@ -50,8 +50,8 @@ impl Report {
|
||||||
/// #
|
/// #
|
||||||
/// # use ffi::{Input, Output};
|
/// # use ffi::{Input, Output};
|
||||||
/// #
|
/// #
|
||||||
/// use miette::{Report, Result};
|
|
||||||
/// use futures::stream::{Stream, StreamExt, TryStreamExt};
|
/// use futures::stream::{Stream, StreamExt, TryStreamExt};
|
||||||
|
/// use miette::{Report, Result};
|
||||||
///
|
///
|
||||||
/// async fn demo<S>(stream: S) -> Result<Vec<Output>>
|
/// async fn demo<S>(stream: S) -> Result<Vec<Output>>
|
||||||
/// where
|
/// where
|
||||||
|
|
@ -193,13 +193,13 @@ impl Report {
|
||||||
|
|
||||||
/// Create a new error from an error message to wrap the existing error.
|
/// Create a new error from an error message to wrap the existing error.
|
||||||
///
|
///
|
||||||
/// For attaching a higher level error message to a `Result` as it is propagated, the
|
/// For attaching a higher level error message to a `Result` as it is
|
||||||
/// [crate::WrapErr] extension trait may be more convenient than this function.
|
/// propagated, the [crate::WrapErr] extension trait may be more
|
||||||
///
|
/// convenient than this function.
|
||||||
/// The primary reason to use `error.wrap_err(...)` instead of `result.wrap_err(...)` via the
|
|
||||||
/// `WrapErr` trait would be if the message needs to depend on some data held by the underlying
|
|
||||||
/// error:
|
|
||||||
///
|
///
|
||||||
|
/// The primary reason to use `error.wrap_err(...)` instead of
|
||||||
|
/// `result.wrap_err(...)` via the `WrapErr` trait would be if the
|
||||||
|
/// message needs to depend on some data held by the underlying error:
|
||||||
pub fn wrap_err<D>(mut self, msg: D) -> Self
|
pub fn wrap_err<D>(mut self, msg: D) -> Self
|
||||||
where
|
where
|
||||||
D: Display + Send + Sync + 'static,
|
D: Display + Send + Sync + 'static,
|
||||||
|
|
@ -258,7 +258,7 @@ impl Report {
|
||||||
/// cause's cause etc.
|
/// cause's cause etc.
|
||||||
///
|
///
|
||||||
/// The root cause is the last error in the iterator produced by
|
/// The root cause is the last error in the iterator produced by
|
||||||
/// [`chain()`][Report::chain].
|
/// [`chain()`](Report::chain).
|
||||||
pub fn root_cause(&self) -> &(dyn StdError + 'static) {
|
pub fn root_cause(&self) -> &(dyn StdError + 'static) {
|
||||||
let mut chain = self.chain();
|
let mut chain = self.chain();
|
||||||
let mut root_cause = chain.next().unwrap();
|
let mut root_cause = chain.next().unwrap();
|
||||||
|
|
@ -270,9 +270,10 @@ impl Report {
|
||||||
|
|
||||||
/// Returns true if `E` is the type held by this error object.
|
/// Returns true if `E` is the type held by this error object.
|
||||||
///
|
///
|
||||||
/// For errors constructed from messages, this method returns true if `E` matches the type of
|
/// For errors constructed from messages, this method returns true if `E`
|
||||||
/// the message `D` **or** the type of the error on which the message has been attached. For
|
/// matches the type of the message `D` **or** the type of the error on
|
||||||
/// details about the interaction between message and downcasting, [see here].
|
/// which the message has been attached. For details about the
|
||||||
|
/// interaction between message and downcasting, [see here].
|
||||||
///
|
///
|
||||||
/// [see here]: trait.WrapErr.html#effect-on-downcasting
|
/// [see here]: trait.WrapErr.html#effect-on-downcasting
|
||||||
pub fn is<E>(&self) -> bool
|
pub fn is<E>(&self) -> bool
|
||||||
|
|
|
||||||
|
|
@ -2,19 +2,20 @@ use thiserror::Error;
|
||||||
|
|
||||||
use crate::{Diagnostic, Report};
|
use crate::{Diagnostic, Report};
|
||||||
|
|
||||||
/// Convenience [Diagnostic] that can be used as an "anonymous" wrapper for
|
/// Convenience [`Diagnostic`] that can be used as an "anonymous" wrapper for
|
||||||
/// Errors. This is intended to be paired with [IntoDiagnostic].
|
/// Errors. This is intended to be paired with [`IntoDiagnostic`].
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
struct DiagnosticError(Box<dyn std::error::Error + Send + Sync + 'static>);
|
struct DiagnosticError(Box<dyn std::error::Error + Send + Sync + 'static>);
|
||||||
impl Diagnostic for DiagnosticError {}
|
impl Diagnostic for DiagnosticError {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Convenience trait that adds a `.into_diagnostic()` method that converts a type to a `Result<T, Report>`.
|
Convenience trait that adds a `.into_diagnostic()` method that converts a type
|
||||||
|
to a `Result<T, Report>`.
|
||||||
*/
|
*/
|
||||||
pub trait IntoDiagnostic<T, E> {
|
pub trait IntoDiagnostic<T, E> {
|
||||||
/// Converts [Result]-like types that return regular errors into a
|
/// Converts [`Result`]-like types that return regular errors into a
|
||||||
/// `Result` that returns a [Diagnostic].
|
/// `Result` that returns a [`Diagnostic`].
|
||||||
fn into_diagnostic(self) -> Result<T, Report>;
|
fn into_diagnostic(self) -> Result<T, Report>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,8 @@ type ErrorHook =
|
||||||
|
|
||||||
static HOOK: OnceCell<ErrorHook> = OnceCell::new();
|
static HOOK: OnceCell<ErrorHook> = OnceCell::new();
|
||||||
|
|
||||||
/// Error indicating that `set_hook` was unable to install the provided ErrorHook
|
/// Error indicating that `set_hook` was unable to install the provided
|
||||||
|
/// ErrorHook
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct InstallError;
|
pub struct InstallError;
|
||||||
|
|
||||||
|
|
@ -139,9 +140,9 @@ pub trait ReportHandler: core::any::Any + Send + Sync {
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
|
/// use indenter::indented;
|
||||||
/// use miette::Diagnostic;
|
/// use miette::Diagnostic;
|
||||||
/// use miette::ReportHandler;
|
/// use miette::ReportHandler;
|
||||||
/// use indenter::indented;
|
|
||||||
///
|
///
|
||||||
/// pub struct Handler;
|
/// pub struct Handler;
|
||||||
///
|
///
|
||||||
|
|
@ -193,8 +194,9 @@ pub trait ReportHandler: core::any::Any + Send + Sync {
|
||||||
|
|
||||||
/// type alias for `Result<T, Report>`
|
/// type alias for `Result<T, Report>`
|
||||||
///
|
///
|
||||||
/// This is a reasonable return type to use throughout your application but also for `fn main`; if
|
/// This is a reasonable return type to use throughout your application but also
|
||||||
/// you do, failures will be printed along with a backtrace if one was captured.
|
/// for `fn main`; if you do, failures will be printed along with a backtrace if
|
||||||
|
/// one was captured.
|
||||||
///
|
///
|
||||||
/// `miette::Result` may be used with one *or* two type parameters.
|
/// `miette::Result` may be used with one *or* two type parameters.
|
||||||
///
|
///
|
||||||
|
|
@ -290,10 +292,11 @@ pub type Result<T, E = Report> = core::result::Result<T, E>;
|
||||||
///
|
///
|
||||||
/// # Wrapping Types That Don't impl `Error` (e.g. `&str` and `Box<dyn Error>`)
|
/// # Wrapping Types That Don't impl `Error` (e.g. `&str` and `Box<dyn Error>`)
|
||||||
///
|
///
|
||||||
/// Due to restrictions for coherence `Report` cannot impl `From` for types that don't impl
|
/// Due to restrictions for coherence `Report` cannot impl `From` for types that
|
||||||
/// `Error`. Attempts to do so will give "this type might implement Error in the future" as an
|
/// don't impl `Error`. Attempts to do so will give "this type might implement
|
||||||
/// error. As such, `wrap_err`, which uses `From` under the hood, cannot be used to wrap these
|
/// Error in the future" as an error. As such, `wrap_err`, which uses `From`
|
||||||
/// types. Instead we encourage you to use the combinators provided for `Result` in `std`/`core`.
|
/// under the hood, cannot be used to wrap these types. Instead we encourage you
|
||||||
|
/// to use the combinators provided for `Result` in `std`/`core`.
|
||||||
///
|
///
|
||||||
/// For example, instead of this:
|
/// For example, instead of this:
|
||||||
///
|
///
|
||||||
|
|
@ -309,18 +312,19 @@ pub type Result<T, E = Report> = core::result::Result<T, E>;
|
||||||
/// We encourage you to write this:
|
/// We encourage you to write this:
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
|
/// use miette::{miette, Report, WrapErr};
|
||||||
/// use std::error::Error;
|
/// use std::error::Error;
|
||||||
/// use miette::{WrapErr, Report, miette};
|
|
||||||
///
|
///
|
||||||
/// fn wrap_example(err: Result<(), Box<dyn Error + Send + Sync + 'static>>) -> Result<(), Report> {
|
/// fn wrap_example(err: Result<(), Box<dyn Error + Send + Sync + 'static>>) -> Result<(), Report> {
|
||||||
/// err.map_err(|e| miette!(e)).wrap_err("saw a downstream error")
|
/// err.map_err(|e| miette!(e))
|
||||||
|
/// .wrap_err("saw a downstream error")
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// # Effect on downcasting
|
/// # Effect on downcasting
|
||||||
///
|
///
|
||||||
/// After attaching a message of type `D` onto an error of type `E`, the resulting
|
/// After attaching a message of type `D` onto an error of type `E`, the
|
||||||
/// `miette::Error` may be downcast to `D` **or** to `E`.
|
/// resulting `miette::Error` may be downcast to `D` **or** to `E`.
|
||||||
///
|
///
|
||||||
/// That is, in codebases that rely on downcasting, miette's wrap_err supports
|
/// That is, in codebases that rely on downcasting, miette's wrap_err supports
|
||||||
/// both of the following use cases:
|
/// both of the following use cases:
|
||||||
|
|
@ -329,10 +333,10 @@ pub type Result<T, E = Report> = core::result::Result<T, E>;
|
||||||
/// is used in downcasts.**
|
/// is used in downcasts.**
|
||||||
///
|
///
|
||||||
/// In other error libraries whose wrap_err is not designed this way, it can
|
/// In other error libraries whose wrap_err is not designed this way, it can
|
||||||
/// be risky to introduce messages to existing code because new message might
|
/// be risky to introduce messages to existing code because new message
|
||||||
/// break existing working downcasts. In miette, any downcast that worked
|
/// might break existing working downcasts. In miette, any downcast that
|
||||||
/// before adding the message will continue to work after you add a message, so
|
/// worked before adding the message will continue to work after you add a
|
||||||
/// you should freely wrap errors wherever it would be helpful.
|
/// message, so you should freely wrap errors wherever it would be helpful.
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// # use miette::bail;
|
/// # use miette::bail;
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ use crate::ThemeCharacters;
|
||||||
use crate::ThemeStyles;
|
use crate::ThemeStyles;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Create a custom [MietteHandler] from options.
|
Create a custom [`MietteHandler`] from options.
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
|
|
||||||
|
|
@ -43,7 +43,7 @@ pub struct MietteHandlerOpts {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MietteHandlerOpts {
|
impl MietteHandlerOpts {
|
||||||
/// Create a new [MietteHandlerOpts].
|
/// Create a new `MietteHandlerOpts`.
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Default::default()
|
Default::default()
|
||||||
}
|
}
|
||||||
|
|
@ -56,15 +56,16 @@ impl MietteHandlerOpts {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set a graphical theme for the handler when rendering in graphical
|
/// Set a graphical theme for the handler when rendering in graphical mode.
|
||||||
/// mode. Use [MietteHandlerOpts::force_graphical] to force graphical
|
/// Use [`force_graphical()`](`MietteHandlerOpts::force_graphical) to force
|
||||||
/// mode. This option overrides [MietteHandlerOpts::color].
|
/// graphical mode. This option overrides
|
||||||
|
/// [`color()`](`MietteHandlerOpts::color).
|
||||||
pub fn graphical_theme(mut self, theme: GraphicalTheme) -> Self {
|
pub fn graphical_theme(mut self, theme: GraphicalTheme) -> Self {
|
||||||
self.theme = Some(theme);
|
self.theme = Some(theme);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the width to wrap the report at. Defaults
|
/// Sets the width to wrap the report at. Defaults to 80.
|
||||||
pub fn width(mut self, width: usize) -> Self {
|
pub fn width(mut self, width: usize) -> Self {
|
||||||
self.width = Some(width);
|
self.width = Some(width);
|
||||||
self
|
self
|
||||||
|
|
@ -126,7 +127,7 @@ impl MietteHandlerOpts {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Builds a [MietteHandler] from this builder.
|
/// Builds a [`MietteHandler`] from this builder.
|
||||||
pub fn build(self) -> MietteHandler {
|
pub fn build(self) -> MietteHandler {
|
||||||
let graphical = self.is_graphical();
|
let graphical = self.is_graphical();
|
||||||
let width = self.get_width();
|
let width = self.get_width();
|
||||||
|
|
@ -216,15 +217,18 @@ impl MietteHandlerOpts {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
A [ReportHandler] that displays a given [crate::Report] in a quasi-graphical
|
A [`ReportHandler`] that displays a given [`Report`](crate::Report) in a
|
||||||
way, using terminal colors, unicode drawing characters, and other such things.
|
quasi-graphical way, using terminal colors, unicode drawing characters, and
|
||||||
|
other such things.
|
||||||
|
|
||||||
This is the default reporter bundled with `miette`.
|
This is the default reporter bundled with `miette`.
|
||||||
|
|
||||||
This printer can be customized by using `new_themed()` and handing it a
|
This printer can be customized by using
|
||||||
[GraphicalTheme] of your own creation (or using one of its own defaults!)
|
[`GraphicalReportHandler::new_themed()`] and handing it a [`GraphicalTheme`] of
|
||||||
|
your own creation (or using one of its own defaults).
|
||||||
|
|
||||||
See [crate::set_hook] for more details on customizing your global printer.
|
See [`set_hook`](crate::set_hook) for more details on customizing your global
|
||||||
|
printer.
|
||||||
*/
|
*/
|
||||||
#[allow(missing_debug_implementations)]
|
#[allow(missing_debug_implementations)]
|
||||||
pub struct MietteHandler {
|
pub struct MietteHandler {
|
||||||
|
|
@ -232,7 +236,7 @@ pub struct MietteHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MietteHandler {
|
impl MietteHandler {
|
||||||
/// Creates a new [MietteHandler] with default settings.
|
/// Creates a new [`MietteHandler`] with default settings.
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Default::default()
|
Default::default()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ use std::fmt;
|
||||||
use crate::{protocol::Diagnostic, ReportHandler};
|
use crate::{protocol::Diagnostic, ReportHandler};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
[ReportHandler] 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
|
It's optimized for screen readers and braille users, but is also used in any
|
||||||
non-graphical environments, such as non-TTY output.
|
non-graphical environments, such as non-TTY output.
|
||||||
*/
|
*/
|
||||||
|
|
@ -11,8 +11,8 @@ non-graphical environments, such as non-TTY output.
|
||||||
pub struct DebugReportHandler;
|
pub struct DebugReportHandler;
|
||||||
|
|
||||||
impl DebugReportHandler {
|
impl DebugReportHandler {
|
||||||
/// Create a new [NarratableReportHandler]. There are no customization
|
/// Create a new [`NarratableReportHandler`](crate::NarratableReportHandler)
|
||||||
/// options.
|
/// There are no customization options.
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self
|
Self
|
||||||
}
|
}
|
||||||
|
|
@ -25,10 +25,9 @@ impl Default for DebugReportHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DebugReportHandler {
|
impl DebugReportHandler {
|
||||||
/// Render a [Diagnostic]. This function is mostly internal and meant to
|
/// Render a [`Diagnostic`]. This function is mostly internal and meant to
|
||||||
/// be called by the toplevel [ReportHandler] handler, but is
|
/// be called by the toplevel [`ReportHandler`] handler, but is made public
|
||||||
/// made public to make it easier (possible) to test in isolation from
|
/// to make it easier (possible) to test in isolation from global state.
|
||||||
/// global state.
|
|
||||||
pub fn render_report(
|
pub fn render_report(
|
||||||
&self,
|
&self,
|
||||||
f: &mut fmt::Formatter<'_>,
|
f: &mut fmt::Formatter<'_>,
|
||||||
|
|
|
||||||
|
|
@ -8,15 +8,17 @@ use crate::protocol::{Diagnostic, Severity};
|
||||||
use crate::{LabeledSpan, MietteError, ReportHandler, SourceCode, SourceSpan, SpanContents};
|
use crate::{LabeledSpan, MietteError, ReportHandler, SourceCode, SourceSpan, SpanContents};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
A [ReportHandler] that displays a given [crate::Report] in a quasi-graphical
|
A [`ReportHandler`] that displays a given [`Report`](crate::Report) in a
|
||||||
way, using terminal colors, unicode drawing characters, and other such things.
|
quasi-graphical way, using terminal colors, unicode drawing characters, and
|
||||||
|
other such things.
|
||||||
|
|
||||||
This is the default reporter bundled with `miette`.
|
This is the default reporter bundled with `miette`.
|
||||||
|
|
||||||
This printer can be customized by using `new_themed()` and handing it a
|
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!)
|
[`GraphicalTheme`] of your own creation (or using one of its own defaults!)
|
||||||
|
|
||||||
See [crate::set_hook] for more details on customizing your global printer.
|
See [`set_hook`](crate::set_hook) for more details on customizing your global
|
||||||
|
printer.
|
||||||
*/
|
*/
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct GraphicalReportHandler {
|
pub struct GraphicalReportHandler {
|
||||||
|
|
@ -29,8 +31,8 @@ pub struct GraphicalReportHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GraphicalReportHandler {
|
impl GraphicalReportHandler {
|
||||||
/// Create a new [GraphicalReportHandler] with the default
|
/// Create a new `GraphicalReportHandler` with the default
|
||||||
/// [GraphicalTheme]. This will use both unicode characters and colors.
|
/// [`GraphicalTheme`]. This will use both unicode characters and colors.
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
linkify_code: true,
|
linkify_code: true,
|
||||||
|
|
@ -42,7 +44,7 @@ impl GraphicalReportHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///Create a new [GraphicalReportHandler] with a given [GraphicalTheme].
|
///Create a new `GraphicalReportHandler` with a given [`GraphicalTheme`].
|
||||||
pub fn new_themed(theme: GraphicalTheme) -> Self {
|
pub fn new_themed(theme: GraphicalTheme) -> Self {
|
||||||
Self {
|
Self {
|
||||||
linkify_code: true,
|
linkify_code: true,
|
||||||
|
|
@ -60,7 +62,7 @@ impl GraphicalReportHandler {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Whether to enable error code linkification using [Diagnostic::url].
|
/// Whether to enable error code linkification using [`Diagnostic::url()`].
|
||||||
pub fn with_links(mut self, links: bool) -> Self {
|
pub fn with_links(mut self, links: bool) -> Self {
|
||||||
self.linkify_code = links;
|
self.linkify_code = links;
|
||||||
self
|
self
|
||||||
|
|
@ -78,7 +80,7 @@ impl GraphicalReportHandler {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the "global" footer for this handler.
|
/// Sets the 'global' footer for this handler.
|
||||||
pub fn with_footer(mut self, footer: String) -> Self {
|
pub fn with_footer(mut self, footer: String) -> Self {
|
||||||
self.footer = Some(footer);
|
self.footer = Some(footer);
|
||||||
self
|
self
|
||||||
|
|
@ -98,10 +100,9 @@ impl Default for GraphicalReportHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GraphicalReportHandler {
|
impl GraphicalReportHandler {
|
||||||
/// Render a [Diagnostic]. This function is mostly internal and meant to
|
/// Render a [`Diagnostic`]. This function is mostly internal and meant to
|
||||||
/// be called by the toplevel [ReportHandler] handler, but is
|
/// be called by the toplevel [`ReportHandler`] handler, but is made public
|
||||||
/// made public to make it easier (possible) to test in isolation from
|
/// to make it easier (possible) to test in isolation from global state.
|
||||||
/// global state.
|
|
||||||
pub fn render_report(
|
pub fn render_report(
|
||||||
&self,
|
&self,
|
||||||
f: &mut impl fmt::Write,
|
f: &mut impl fmt::Write,
|
||||||
|
|
@ -294,8 +295,8 @@ impl GraphicalReportHandler {
|
||||||
{
|
{
|
||||||
contexts.pop();
|
contexts.pop();
|
||||||
contexts.push((
|
contexts.push((
|
||||||
new_span, // We'll throw this away later
|
// We'll throw this away later
|
||||||
left_conts,
|
new_span, left_conts,
|
||||||
));
|
));
|
||||||
} else {
|
} else {
|
||||||
contexts.push((right, right_conts));
|
contexts.push((right, right_conts));
|
||||||
|
|
@ -346,7 +347,8 @@ impl GraphicalReportHandler {
|
||||||
max_gutter = std::cmp::max(max_gutter, num_highlights);
|
max_gutter = std::cmp::max(max_gutter, num_highlights);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Oh and one more thing: We need to figure out how much room our line numbers need!
|
// Oh and one more thing: We need to figure out how much room our line
|
||||||
|
// numbers need!
|
||||||
let linum_width = lines[..]
|
let linum_width = lines[..]
|
||||||
.last()
|
.last()
|
||||||
.expect("get_lines should always return at least one line?")
|
.expect("get_lines should always return at least one line?")
|
||||||
|
|
@ -569,7 +571,8 @@ impl GraphicalReportHandler {
|
||||||
let hl_len = std::cmp::max(1, hl.len());
|
let hl_len = std::cmp::max(1, hl.len());
|
||||||
|
|
||||||
let local_offset = if let Some(w) = self.tab_width {
|
let local_offset = if let Some(w) = self.tab_width {
|
||||||
// Only count tabs that affect the position of the highlighted line and ignore tabs past the span.
|
// Only count tabs that affect the position of the highlighted
|
||||||
|
// line and ignore tabs past the span.
|
||||||
let tab_count = &line.text[..hl.offset() - line.offset].matches('\t').count();
|
let tab_count = &line.text[..hl.offset() - line.offset].matches('\t').count();
|
||||||
let tabs_as_spaces = tab_count * w - tab_count;
|
let tabs_as_spaces = tab_count * w - tab_count;
|
||||||
hl.offset() - line.offset + tabs_as_spaces
|
hl.offset() - line.offset + tabs_as_spaces
|
||||||
|
|
@ -610,7 +613,8 @@ impl GraphicalReportHandler {
|
||||||
.iter()
|
.iter()
|
||||||
.map(|hl| {
|
.map(|hl| {
|
||||||
let local_offset = if let Some(w) = self.tab_width {
|
let local_offset = if let Some(w) = self.tab_width {
|
||||||
// Only count tabs that affect the position of the highlighted line and ignore tabs past the span.
|
// Only count tabs that affect the position of the
|
||||||
|
// highlighted line and ignore tabs past the span.
|
||||||
let tab_count = &line.text[..hl.offset() - line.offset].matches('\t').count();
|
let tab_count = &line.text[..hl.offset() - line.offset].matches('\t').count();
|
||||||
let tabs_as_spaces = tab_count * w - tab_count;
|
let tabs_as_spaces = tab_count * w - tab_count;
|
||||||
hl.offset() - line.offset + tabs_as_spaces
|
hl.offset() - line.offset + tabs_as_spaces
|
||||||
|
|
@ -756,11 +760,12 @@ impl Line {
|
||||||
|| (span.offset() + span.len() > self.offset && span.offset() + span.len() <= self.offset + self.length)
|
|| (span.offset() + span.len() > self.offset && span.offset() + span.len() <= self.offset + self.length)
|
||||||
}
|
}
|
||||||
|
|
||||||
// A "flyby" is a multi-line span that technically covers this line, but
|
// A 'flyby' is a multi-line span that technically covers this line, but
|
||||||
// does not begin or end within the line itself. This method is used to
|
// does not begin or end within the line itself. This method is used to
|
||||||
// calculate gutters.
|
// calculate gutters.
|
||||||
fn span_flyby(&self, span: &FancySpan) -> bool {
|
fn span_flyby(&self, span: &FancySpan) -> bool {
|
||||||
// the span itself starts before this line's starting offset (so, in a prev line)
|
// The span itself starts before this line's starting offset (so, in a
|
||||||
|
// prev line).
|
||||||
span.offset() < self.offset
|
span.offset() < self.offset
|
||||||
// ...and it stops after this line's end.
|
// ...and it stops after this line's end.
|
||||||
&& span.offset() + span.len() > self.offset + self.length
|
&& span.offset() + span.len() > self.offset + self.length
|
||||||
|
|
|
||||||
|
|
@ -3,14 +3,13 @@ use std::fmt::{self, Write};
|
||||||
use crate::{protocol::Diagnostic, ReportHandler, Severity, SourceCode};
|
use crate::{protocol::Diagnostic, ReportHandler, Severity, SourceCode};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
[ReportHandler] that renders json output.
|
[`ReportHandler`] that renders JSON output. It's a machine-readable output.
|
||||||
It's a machine-readable output.
|
|
||||||
*/
|
*/
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct JSONReportHandler;
|
pub struct JSONReportHandler;
|
||||||
|
|
||||||
impl JSONReportHandler {
|
impl JSONReportHandler {
|
||||||
/// Create a new [JSONReportHandler]. There are no customization
|
/// Create a new [`JSONReportHandler`]. There are no customization
|
||||||
/// options.
|
/// options.
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self
|
Self
|
||||||
|
|
@ -54,10 +53,9 @@ fn escape(input: &'_ str) -> Escape<'_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl JSONReportHandler {
|
impl JSONReportHandler {
|
||||||
/// Render a [Diagnostic]. This function is mostly internal and meant to
|
/// Render a [`Diagnostic`]. This function is mostly internal and meant to
|
||||||
/// be called by the toplevel [ReportHandler] handler, but is
|
/// be called by the toplevel [`ReportHandler`] handler, but is made public
|
||||||
/// made public to make it easier (possible) to test in isolation from
|
/// to make it easier (possible) to test in isolation from global state.
|
||||||
/// global state.
|
|
||||||
pub fn render_report(
|
pub fn render_report(
|
||||||
&self,
|
&self,
|
||||||
f: &mut impl fmt::Write,
|
f: &mut impl fmt::Write,
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ use crate::protocol::{Diagnostic, Severity};
|
||||||
use crate::{LabeledSpan, MietteError, ReportHandler, SourceCode, SourceSpan, SpanContents};
|
use crate::{LabeledSpan, MietteError, ReportHandler, SourceCode, SourceSpan, SpanContents};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
[ReportHandler] 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
|
It's optimized for screen readers and braille users, but is also used in any
|
||||||
non-graphical environments, such as non-TTY output.
|
non-graphical environments, such as non-TTY output.
|
||||||
*/
|
*/
|
||||||
|
|
@ -18,7 +18,7 @@ pub struct NarratableReportHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NarratableReportHandler {
|
impl NarratableReportHandler {
|
||||||
/// Create a new [NarratableReportHandler]. There are no customization
|
/// Create a new [`NarratableReportHandler`]. There are no customization
|
||||||
/// options.
|
/// options.
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
|
@ -47,8 +47,8 @@ impl Default for NarratableReportHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NarratableReportHandler {
|
impl NarratableReportHandler {
|
||||||
/// Render a [Diagnostic]. This function is mostly internal and meant to
|
/// Render a [`Diagnostic`]. This function is mostly internal and meant to
|
||||||
/// be called by the toplevel [ReportHandler] handler, but is
|
/// be called by the toplevel [`ReportHandler`] handler, but is
|
||||||
/// made public to make it easier (possible) to test in isolation from
|
/// made public to make it easier (possible) to test in isolation from
|
||||||
/// global state.
|
/// global state.
|
||||||
pub fn render_report(
|
pub fn render_report(
|
||||||
|
|
@ -345,7 +345,8 @@ enum SpanAttach {
|
||||||
Ends { col_end: usize },
|
Ends { col_end: usize },
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns column at offset, and nearest boundary if offset is in the middle of the character
|
/// Returns column at offset, and nearest boundary if offset is in the middle of
|
||||||
|
/// the character
|
||||||
fn safe_get_column(text: &str, offset: usize, start: bool) -> usize {
|
fn safe_get_column(text: &str, offset: usize, start: bool) -> usize {
|
||||||
let mut column = text.get(0..offset).map(|s| s.width()).unwrap_or_else(|| {
|
let mut column = text.get(0..offset).map(|s| s.width()).unwrap_or_else(|| {
|
||||||
let mut column = 0;
|
let mut column = 0;
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,12 @@ use atty::Stream;
|
||||||
use owo_colors::Style;
|
use owo_colors::Style;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Theme used by [crate::GraphicalReportHandler] to render fancy [crate::Diagnostic] reports.
|
Theme used by [`GraphicalReportHandler`](crate::GraphicalReportHandler) to
|
||||||
|
render fancy [`Diagnostic`](crate::Diagnostic) reports.
|
||||||
|
|
||||||
A theme consists of two things: the set of characters to be used for drawing,
|
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.
|
and the
|
||||||
|
[`owo_colors::Style`](https://docs.rs/owo-colors/latest/owo_colors/struct.Style.html)s to be used to paint various items.
|
||||||
|
|
||||||
You can create your own custom graphical theme using this type, or you can use
|
You can create your own custom graphical theme using this type, or you can use
|
||||||
one of the predefined ones using the methods below.
|
one of the predefined ones using the methods below.
|
||||||
|
|
@ -27,7 +29,8 @@ impl GraphicalTheme {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Graphical theme that draws using both ansi colors and unicode characters.
|
/// Graphical theme that draws using both ansi colors and unicode
|
||||||
|
/// characters.
|
||||||
pub fn unicode() -> Self {
|
pub fn unicode() -> Self {
|
||||||
Self {
|
Self {
|
||||||
characters: ThemeCharacters::unicode(),
|
characters: ThemeCharacters::unicode(),
|
||||||
|
|
@ -95,7 +98,7 @@ fn style() -> Style {
|
||||||
|
|
||||||
impl ThemeStyles {
|
impl ThemeStyles {
|
||||||
/// Nice RGB colors.
|
/// Nice RGB colors.
|
||||||
/// Credit: http://terminal.sexy/#FRUV0NDQFRUVrEFCkKlZ9L91ap-1qnWfdbWq0NDQUFBQrEFCkKlZ9L91ap-1qnWfdbWq9fX1
|
/// [Credit](http://terminal.sexy/#FRUV0NDQFRUVrEFCkKlZ9L91ap-1qnWfdbWq0NDQUFBQrEFCkKlZ9L91ap-1qnWfdbWq9fX1).
|
||||||
pub fn rgb() -> Self {
|
pub fn rgb() -> Self {
|
||||||
Self {
|
Self {
|
||||||
error: style().fg_rgb::<255, 30, 30>(),
|
error: style().fg_rgb::<255, 30, 30>(),
|
||||||
|
|
@ -143,11 +146,12 @@ impl ThemeStyles {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------
|
// ----------------------------------------
|
||||||
// Most of these characters were taken from
|
// Most of these characters were taken from
|
||||||
// https://github.com/zesterer/ariadne/blob/e3cb394cb56ecda116a0a1caecd385a49e7f6662/src/draw.rs
|
// https://github.com/zesterer/ariadne/blob/e3cb394cb56ecda116a0a1caecd385a49e7f6662/src/draw.rs
|
||||||
|
|
||||||
/// Characters to be used when drawing when using [crate::GraphicalReportHandler].
|
/// Characters to be used when drawing when using
|
||||||
|
/// [crate::GraphicalReportHandler].
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||||
pub struct ThemeCharacters {
|
pub struct ThemeCharacters {
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
use crate::{MietteError, MietteSpanContents, SourceCode, SpanContents};
|
use crate::{MietteError, MietteSpanContents, SourceCode, SpanContents};
|
||||||
|
|
||||||
/// Utility struct for when you have a regular [Source] type, such as a String,
|
/// Utility struct for when you have a regular [`SourceCode`] type, such as a
|
||||||
/// that doesn't implement `name`, or if you want to override the `.name()`
|
/// String, that doesn't implement `name`, or if you want to override the
|
||||||
/// returned by the `Source`.
|
/// `.name()` returned by the `SourceCode`.
|
||||||
pub struct NamedSource {
|
pub struct NamedSource {
|
||||||
source: Box<dyn SourceCode + 'static>,
|
source: Box<dyn SourceCode + 'static>,
|
||||||
name: String,
|
name: String,
|
||||||
|
|
@ -18,7 +18,8 @@ impl std::fmt::Debug for NamedSource {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NamedSource {
|
impl NamedSource {
|
||||||
/// Create a new [NamedSource] using a regular [SourceCode] and giving its returned [SpanContents] a name.
|
/// Create a new `NamedSource` using a regular [`SourceCode`] and giving
|
||||||
|
/// its returned [`SpanContents`] a name.
|
||||||
pub fn new(name: impl AsRef<str>, source: impl SourceCode + Send + Sync + 'static) -> Self {
|
pub fn new(name: impl AsRef<str>, source: impl SourceCode + Send + Sync + 'static) -> Self {
|
||||||
Self {
|
Self {
|
||||||
source: Box::new(source),
|
source: Box::new(source),
|
||||||
|
|
@ -26,7 +27,8 @@ impl NamedSource {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a reference the inner [SourceCode] type for this [NamedSource].
|
/// Returns a reference the inner [`SourceCode`] type for this
|
||||||
|
/// `NamedSource`.
|
||||||
pub fn inner(&self) -> &(dyn SourceCode + 'static) {
|
pub fn inner(&self) -> &(dyn SourceCode + 'static) {
|
||||||
&*self.source
|
&*self.source
|
||||||
}
|
}
|
||||||
|
|
|
||||||
110
src/protocol.rs
110
src/protocol.rs
|
|
@ -1,9 +1,8 @@
|
||||||
/*!
|
/*!
|
||||||
This module defines the core of the miette protocol: a series of types and traits
|
This module defines the core of the miette protocol: a series of types and
|
||||||
that you can implement to get access to miette's (and related library's) full
|
traits that you can implement to get access to miette's (and related library's)
|
||||||
reporting and such features.
|
full reporting and such features.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
fmt::{self, Display},
|
fmt::{self, Display},
|
||||||
fs,
|
fs,
|
||||||
|
|
@ -12,50 +11,51 @@ use std::{
|
||||||
|
|
||||||
use crate::MietteError;
|
use crate::MietteError;
|
||||||
|
|
||||||
/**
|
/// Adds rich metadata to your Error that can be used by
|
||||||
Adds rich metadata to your Error that can be used by [Report] to print
|
/// [`Report`](crate::Report) to print really nice and human-friendly error
|
||||||
really nice and human-friendly error messages.
|
/// messages.
|
||||||
*/
|
|
||||||
pub trait Diagnostic: std::error::Error {
|
pub trait Diagnostic: std::error::Error {
|
||||||
/// Unique diagnostic code that can be used to look up more information
|
/// Unique diagnostic code that can be used to look up more information
|
||||||
/// about this Diagnostic. Ideally also globally unique, and documented in
|
/// about this `Diagnostic`. Ideally also globally unique, and documented
|
||||||
/// the toplevel crate's documentation for easy searching. Rust path
|
/// in the toplevel crate's documentation for easy searching. Rust path
|
||||||
/// format (`foo::bar::baz`) is recommended, but more classic codes like
|
/// format (`foo::bar::baz`) is recommended, but more classic codes like
|
||||||
/// `E0123` or Enums will work just fine.
|
/// `E0123` or enums will work just fine.
|
||||||
fn code<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
|
fn code<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Diagnostic severity. This may be used by [ReportHandler]s to change the
|
/// Diagnostic severity. This may be used by
|
||||||
/// display format of this diagnostic.
|
/// [`ReportHandler`](crate::ReportHandler)s to change the display format
|
||||||
|
/// of this diagnostic.
|
||||||
///
|
///
|
||||||
/// If `None`, reporters should treat this as [Severity::Error]
|
/// If `None`, reporters should treat this as [`Severity::Error`].
|
||||||
fn severity(&self) -> Option<Severity> {
|
fn severity(&self) -> Option<Severity> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Additional help text related to this Diagnostic. Do you have any
|
/// Additional help text related to this `Diagnostic`. Do you have any
|
||||||
/// advice for the poor soul who's just run into this issue?
|
/// advice for the poor soul who's just run into this issue?
|
||||||
fn help<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
|
fn help<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
/// URL to visit for a more detailed explanation/help about this Diagnostic.
|
/// URL to visit for a more detailed explanation/help about this
|
||||||
|
/// `Diagnostic`.
|
||||||
fn url<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
|
fn url<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Source code to apply this Diagnostic's [Diagnostic::labels] to.
|
/// Source code to apply this `Diagnostic`'s [`Diagnostic::labels`] to.
|
||||||
fn source_code(&self) -> Option<&dyn SourceCode> {
|
fn source_code(&self) -> Option<&dyn SourceCode> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Labels to apply to this Diagnostic's [Diagnostic::source_code]
|
/// Labels to apply to this `Diagnostic`'s [`Diagnostic::source_code`]
|
||||||
fn labels(&self) -> Option<Box<dyn Iterator<Item = LabeledSpan> + '_>> {
|
fn labels(&self) -> Option<Box<dyn Iterator<Item = LabeledSpan> + '_>> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Additional related Diagnostics.
|
/// Additional related `Diagnostic`s.
|
||||||
fn related<'a>(&'a self) -> Option<Box<dyn Iterator<Item = &'a dyn Diagnostic> + 'a>> {
|
fn related<'a>(&'a self) -> Option<Box<dyn Iterator<Item = &'a dyn Diagnostic> + 'a>> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
@ -153,8 +153,9 @@ impl From<Box<dyn std::error::Error + Send + Sync>> for Box<dyn Diagnostic + Sen
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
[Diagnostic] severity. Intended to be used by [ReportHandler]s to change the
|
[`Diagnostic`] severity. Intended to be used by
|
||||||
way different Diagnostics are displayed.
|
[`ReportHandler`](crate::ReportHandler)s to change the way different
|
||||||
|
[`Diagnostic`]s are displayed.
|
||||||
*/
|
*/
|
||||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||||
pub enum Severity {
|
pub enum Severity {
|
||||||
|
|
@ -169,13 +170,13 @@ pub enum Severity {
|
||||||
/**
|
/**
|
||||||
Represents readable source code of some sort.
|
Represents readable source code of some sort.
|
||||||
|
|
||||||
This trait is able to support simple Source types like [String]s, as well
|
This trait is able to support simple `SourceCode` types like [`String`]s, as
|
||||||
as more involved types like indexes into centralized `SourceMap`-like types,
|
well as more involved types like indexes into centralized `SourceMap`-like
|
||||||
file handles, and even network streams.
|
types, file handles, and even network streams.
|
||||||
|
|
||||||
If you can read it, you can source it,
|
If you can read it, you can source it, and it's not necessary to read the
|
||||||
and it's not necessary to read the whole thing--meaning you should be able to
|
whole thing--meaning you should be able to support `SourceCode`s which are
|
||||||
support SourceCodes which are gigabytes or larger in size.
|
gigabytes or larger in size.
|
||||||
*/
|
*/
|
||||||
pub trait SourceCode: Send + Sync {
|
pub trait SourceCode: Send + Sync {
|
||||||
/// Read the bytes for a specific span from this SourceCode, keeping a
|
/// Read the bytes for a specific span from this SourceCode, keeping a
|
||||||
|
|
@ -188,9 +189,7 @@ pub trait SourceCode: Send + Sync {
|
||||||
) -> Result<Box<dyn SpanContents<'a> + 'a>, MietteError>;
|
) -> Result<Box<dyn SpanContents<'a> + 'a>, MietteError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// A labeled [`SourceSpan`].
|
||||||
A labeled [SourceSpan].
|
|
||||||
*/
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct LabeledSpan {
|
pub struct LabeledSpan {
|
||||||
label: Option<String>,
|
label: Option<String>,
|
||||||
|
|
@ -214,12 +213,12 @@ impl LabeledSpan {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the (optional) label string for this LabeledSpan.
|
/// Gets the (optional) label string for this `LabeledSpan`.
|
||||||
pub fn label(&self) -> Option<&str> {
|
pub fn label(&self) -> Option<&str> {
|
||||||
self.label.as_deref()
|
self.label.as_deref()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a reference to the inner [SourceSpan].
|
/// Returns a reference to the inner [`SourceSpan`].
|
||||||
pub fn inner(&self) -> &SourceSpan {
|
pub fn inner(&self) -> &SourceSpan {
|
||||||
&self.span
|
&self.span
|
||||||
}
|
}
|
||||||
|
|
@ -229,52 +228,53 @@ impl LabeledSpan {
|
||||||
self.span.offset()
|
self.span.offset()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the number of bytes this LabeledSpan spans.
|
/// Returns the number of bytes this `LabeledSpan` spans.
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
self.span.len()
|
self.span.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// True if this LabeledSpan is empty.
|
/// True if this `LabeledSpan` is empty.
|
||||||
pub fn is_empty(&self) -> bool {
|
pub fn is_empty(&self) -> bool {
|
||||||
self.span.is_empty()
|
self.span.is_empty()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Contents of a [SourceCode] covered by [SourceSpan].
|
Contents of a [`SourceCode`] covered by [`SourceSpan`].
|
||||||
|
|
||||||
Includes line and column information to optimize highlight calculations.
|
Includes line and column information to optimize highlight calculations.
|
||||||
*/
|
*/
|
||||||
pub trait SpanContents<'a> {
|
pub trait SpanContents<'a> {
|
||||||
/// Reference to the data inside the associated span, in bytes.
|
/// Reference to the data inside the associated span, in bytes.
|
||||||
fn data(&self) -> &'a [u8];
|
fn data(&self) -> &'a [u8];
|
||||||
/// [SourceSpan] representing the span covered by this SpanContents.
|
/// [`SourceSpan`] representing the span covered by this `SpanContents`.
|
||||||
fn span(&self) -> &SourceSpan;
|
fn span(&self) -> &SourceSpan;
|
||||||
/// An optional (file?) name for the container of this SpanContents.
|
/// An optional (file?) name for the container of this `SpanContents`.
|
||||||
fn name(&self) -> Option<&str> {
|
fn name(&self) -> Option<&str> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
/// The 0-indexed line in the associated [SourceCode] where the data begins.
|
/// The 0-indexed line in the associated [`SourceCode`] where the data
|
||||||
|
/// begins.
|
||||||
fn line(&self) -> usize;
|
fn line(&self) -> usize;
|
||||||
/// The 0-indexed column in the associated [SourceCode] where the data begins,
|
/// The 0-indexed column in the associated [`SourceCode`] where the data
|
||||||
/// relative to `line`.
|
/// begins, relative to `line`.
|
||||||
fn column(&self) -> usize;
|
fn column(&self) -> usize;
|
||||||
/// Total number of lines covered by this SpanContents.
|
/// Total number of lines covered by this `SpanContents`.
|
||||||
fn line_count(&self) -> usize;
|
fn line_count(&self) -> usize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Basic implementation of the [SpanContents] trait, for convenience.
|
Basic implementation of the [`SpanContents`] trait, for convenience.
|
||||||
*/
|
*/
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct MietteSpanContents<'a> {
|
pub struct MietteSpanContents<'a> {
|
||||||
// Data from a [SourceCode], in bytes.
|
// Data from a [`SourceCode`], in bytes.
|
||||||
data: &'a [u8],
|
data: &'a [u8],
|
||||||
// span actually covered by this SpanContents.
|
// span actually covered by this SpanContents.
|
||||||
span: SourceSpan,
|
span: SourceSpan,
|
||||||
// The 0-indexed line where the associated [SourceSpan] _starts_.
|
// The 0-indexed line where the associated [`SourceSpan`] _starts_.
|
||||||
line: usize,
|
line: usize,
|
||||||
// The 0-indexed column where the associated [SourceSpan] _starts_.
|
// The 0-indexed column where the associated [`SourceSpan`] _starts_.
|
||||||
column: usize,
|
column: usize,
|
||||||
// Number of line in this snippet.
|
// Number of line in this snippet.
|
||||||
line_count: usize,
|
line_count: usize,
|
||||||
|
|
@ -283,7 +283,7 @@ pub struct MietteSpanContents<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> MietteSpanContents<'a> {
|
impl<'a> MietteSpanContents<'a> {
|
||||||
/// Make a new [MietteSpanContents] object.
|
/// Make a new [`MietteSpanContents`] object.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
data: &'a [u8],
|
data: &'a [u8],
|
||||||
span: SourceSpan,
|
span: SourceSpan,
|
||||||
|
|
@ -301,7 +301,7 @@ impl<'a> MietteSpanContents<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Make a new [MietteSpanContents] object, with a name for its "file".
|
/// Make a new [`MietteSpanContents`] object, with a name for its 'file'.
|
||||||
pub fn new_named(
|
pub fn new_named(
|
||||||
name: String,
|
name: String,
|
||||||
data: &'a [u8],
|
data: &'a [u8],
|
||||||
|
|
@ -343,7 +343,7 @@ impl<'a> SpanContents<'a> for MietteSpanContents<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Span within a [SourceCode] with an associated message.
|
Span within a [`SourceCode`] with an associated message.
|
||||||
*/
|
*/
|
||||||
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
|
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
|
||||||
pub struct SourceSpan {
|
pub struct SourceSpan {
|
||||||
|
|
@ -354,7 +354,7 @@ pub struct SourceSpan {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SourceSpan {
|
impl SourceSpan {
|
||||||
/// Create a new [SourceSpan].
|
/// Create a new [`SourceSpan`].
|
||||||
pub fn new(start: SourceOffset, length: SourceOffset) -> Self {
|
pub fn new(start: SourceOffset, length: SourceOffset) -> Self {
|
||||||
Self {
|
Self {
|
||||||
offset: start,
|
offset: start,
|
||||||
|
|
@ -362,17 +362,17 @@ impl SourceSpan {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The absolute offset, in bytes, from the beginning of a [SourceCode].
|
/// The absolute offset, in bytes, from the beginning of a [`SourceCode`].
|
||||||
pub fn offset(&self) -> usize {
|
pub fn offset(&self) -> usize {
|
||||||
self.offset.offset()
|
self.offset.offset()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Total length of the [SourceSpan], in bytes.
|
/// Total length of the [`SourceSpan`], in bytes.
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
self.length.offset()
|
self.length.offset()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Whether this [SourceSpan] has a length of zero. It may still be useful
|
/// Whether this [`SourceSpan`] has a length of zero. It may still be useful
|
||||||
/// to point to a specific point.
|
/// to point to a specific point.
|
||||||
pub fn is_empty(&self) -> bool {
|
pub fn is_empty(&self) -> bool {
|
||||||
self.length.offset() == 0
|
self.length.offset() == 0
|
||||||
|
|
@ -407,12 +407,12 @@ impl From<std::ops::Range<ByteOffset>> for SourceSpan {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
"Raw" type for the byte offset from the beginning of a [SourceCode].
|
"Raw" type for the byte offset from the beginning of a [`SourceCode`].
|
||||||
*/
|
*/
|
||||||
pub type ByteOffset = usize;
|
pub type ByteOffset = usize;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Newtype that represents the [ByteOffset] from the beginning of a [SourceCode]
|
Newtype that represents the [`ByteOffset`] from the beginning of a [`SourceCode`]
|
||||||
*/
|
*/
|
||||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
|
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
|
||||||
pub struct SourceOffset(ByteOffset);
|
pub struct SourceOffset(ByteOffset);
|
||||||
|
|
@ -453,7 +453,7 @@ impl SourceOffset {
|
||||||
/// function's caller with `#[track_caller]` (and so on and so forth).
|
/// function's caller with `#[track_caller]` (and so on and so forth).
|
||||||
///
|
///
|
||||||
/// Returns both the filename that was given and the offset of the caller
|
/// Returns both the filename that was given and the offset of the caller
|
||||||
/// as a SourceOffset
|
/// as a [`SourceOffset`].
|
||||||
///
|
///
|
||||||
/// Keep in mind that this fill only work if the file your Rust source
|
/// Keep in mind that this fill only work if the file your Rust source
|
||||||
/// file was compiled from is actually available at that location. If
|
/// file was compiled from is actually available at that location. If
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*!
|
/*!
|
||||||
Default trait implementations for [SourceCode].
|
Default trait implementations for [`SourceCode`].
|
||||||
*/
|
*/
|
||||||
use std::{
|
use std::{
|
||||||
borrow::{Cow, ToOwned},
|
borrow::{Cow, ToOwned},
|
||||||
|
|
@ -172,8 +172,11 @@ impl<T: SourceCode> SourceCode for Arc<T> {
|
||||||
|
|
||||||
impl<T: ?Sized + SourceCode + ToOwned> SourceCode for Cow<'_, T>
|
impl<T: ?Sized + SourceCode + ToOwned> SourceCode for Cow<'_, T>
|
||||||
where
|
where
|
||||||
// The minimal bounds are used here. `T::Owned` need not be `SourceCode`,
|
// The minimal bounds are used here.
|
||||||
// because `&T` can always be obtained from `Cow<'_, T>`.
|
// `T::Owned` need not be
|
||||||
|
// `SourceCode`, because `&T`
|
||||||
|
// can always be obtained from
|
||||||
|
// `Cow<'_, T>`.
|
||||||
T::Owned: Debug + Send + Sync,
|
T::Owned: Debug + Send + Sync,
|
||||||
{
|
{
|
||||||
fn read_span<'a>(
|
fn read_span<'a>(
|
||||||
|
|
|
||||||
|
|
@ -652,7 +652,8 @@ fn multiple_multiline_highlights_adjacent() -> Result<(), MietteError> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
// TODO: This breaks because those highlights aren't "truly" overlapping (in absolute byte offset), but they ARE overlapping in lines. Need to detect the latter case better
|
// TODO: This breaks because those highlights aren't "truly" overlapping (in absolute byte offset),
|
||||||
|
// but they ARE overlapping in lines. Need to detect the latter case better
|
||||||
#[ignore]
|
#[ignore]
|
||||||
/// Lines are overlapping, but the offsets themselves aren't, so they _look_
|
/// Lines are overlapping, but the offsets themselves aren't, so they _look_
|
||||||
/// disjunct if you only look at offsets.
|
/// disjunct if you only look at offsets.
|
||||||
|
|
|
||||||
|
|
@ -481,7 +481,8 @@ diagnostic code: oops::my::bad
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
// TODO: This breaks because those highlights aren't "truly" overlapping (in absolute byte offset), but they ARE overlapping in lines. Need to detect the latter case better
|
// TODO: This breaks because those highlights aren't "truly" overlapping (in absolute byte offset),
|
||||||
|
// but they ARE overlapping in lines. Need to detect the latter case better
|
||||||
#[ignore]
|
#[ignore]
|
||||||
/// Lines are overlapping, but the offsets themselves aren't, so they _look_
|
/// Lines are overlapping, but the offsets themselves aren't, so they _look_
|
||||||
/// disjunct if you only look at offsets.
|
/// disjunct if you only look at offsets.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue