Fixed/formatted all intradoc links. Various other small doc fixes/typography/etc.

This commit is contained in:
Moritz Moeller 2022-02-25 01:37:24 +01:00
parent 50bcec909a
commit ccc97310fa
17 changed files with 248 additions and 212 deletions

103
README.md
View File

@ -24,8 +24,8 @@ but it's definitely a bug and should be reported.
diagnostic error code: ruget::api::bad_json
" />
**NOTE: You must enable the `"fancy"` crate feature to get fancy report output
like in the screenshots here.** You should only do this in your toplevel
> **NOTE: You must enable the `"fancy"` crate feature to get fancy report
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
and such might not want.
@ -49,22 +49,25 @@ and such might not want.
## Features
- Generic [Diagnostic] protocol, compatible (and dependent on) `std::error::Error`.
- Unique error codes on every [Diagnostic].
- Generic [`Diagnostic`] protocol, compatible (and dependent on) `std::error::Error`.
- Unique error codes on every [`Diagnostic`].
- Custom links to get more details on error codes.
- Super handy derive macro for defining diagnostic metadata.
- [`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 [SourceCode]s for snippet data, with default support for `String`s included.
- [`anyhow`](https://docs.rs/anyhow)/[`eyre`](https://docs.rs/eyre) error
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.
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
- 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).
- 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
@ -84,7 +87,7 @@ $ cargo add miette --features fancy
```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`!
*/
@ -111,9 +114,9 @@ struct MyBad {
/*
Now let's define a function!
Use this Result type (or its expanded version) as the return type
throughout your app (but NOT your libraries! Those should always return concrete
types!).
Use this `Result` type (or its expanded version) as the return type
throughout your app (but NOT your libraries! Those should always return
concrete types!).
*/
use miette::{Result, NamedSource};
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!
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<()> {
// 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
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
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`.
```rust
@ -194,7 +199,7 @@ pub enum MyLibError {
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
using something like [Report] in a library.
using something like [`Report`] in a library.
### ... 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
external libraries and tools.
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
[Result] type alias that you can use to be more terse.
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
[`Result`] type alias that you can use to be more terse.
When dealing with non-`Diagnostic` types, you'll want to `.into_diagnostic()`
them:
@ -237,11 +242,11 @@ pub fn some_tool() -> Result<Version> {
### ... in `main()`
`main()` is just like any other part of your application-internal code. Use
`Result` as your return value, and it will pretty-print your
diagnostics automatically.
`Result` as your return value, and it will pretty-print your diagnostics
automatically.
**NOTE: You must enable the `"fancy"` crate feature to get fancy report output
like in the screenshots here.** You should only do this in your toplevel
> **NOTE:** You must enable the `"fancy"` crate feature to get fancy report
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
and such might not want.
@ -297,10 +302,10 @@ struct MyErr;
```
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
instead of manually constructing the URL. This will automatically create a
link to this diagnostic on `docs.rs`, so folks can just go straight to
your (very high quality and detailed!) documentation on this diagnostic:
from your crate's top level, you can use a special `url(docsrs)` option instead
of manually constructing the URL. This will automatically create a link to this
diagnostic on `docs.rs`, so folks can just go straight to your (very high
quality and detailed!) documentation on this diagnostic:
```rust
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
it to print out sections of your own source code!
To achieve this, `miette` defines its own lightweight [SourceSpan] type. This
is a basic byte-offset and length into an associated [SourceCode] and, along
To achieve this, `miette` defines its own lightweight [`SourceSpan`] type. This
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
some snippets! You can also use your own `Into<SourceSpan>` types as label
spans.
@ -352,7 +357,7 @@ pub struct MyErrorType {
// You can add as many labels as you want.
// They'll be rendered sequentially.
#[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
printing them all together nicely.
To do so, use the `#[related]` tag on any `IntoIter` field in your
`Diagnostic` type:
To do so, use the `#[related]` tag on any `IntoIter` field in your `Diagnostic`
type:
```rust
use miette::Diagnostic;
@ -379,7 +384,7 @@ struct MyError {
### ... 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
option is to use [`with_source_code()`](Report::with_source_code) method for
that:
```rust,no_run
@ -458,8 +463,8 @@ fn main() -> miette::Result<()> {
### ... handler options
[MietteHandler] is the default handler, and is very customizable. In most
cases, you can simply use [MietteHandlerOpts] to tweak its behavior instead
[`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:
@ -477,29 +482,31 @@ miette::set_hook(Box::new(|_| {
# .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
`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
[`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.
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.
- `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).
`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

View File

@ -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 {
let member_idents = fields.iter().enumerate().map(|(i, 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 members can be passed to `Display::expand_shorthand[_cloned]`.
/// The returned tokens go in the slot `let Self #pat = self;` or `match self {
/// 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>) {
let pat = gen_fields_pat(fields);
let members: HashSet<syn::Member> = fields
@ -125,7 +127,8 @@ pub(crate) fn display_pat_members(fields: &syn::Fields) -> (TokenStream, HashSet
}
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(
&self,
members: &HashSet<syn::Member>,

View File

@ -9,13 +9,14 @@ Error enum for miette. Used by certain operations in the protocol.
*/
#[derive(Debug, Diagnostic, Error)]
pub enum MietteError {
/// Wrapper around [std::io::Error]. This is returned when something went
/// wrong while reading a [crate::Source].
/// Wrapper around [`std::io::Error`]. This is returned when something went
/// wrong while reading a [`SourceCode`](crate::SourceCode).
#[error(transparent)]
#[diagnostic(code(miette::io_error), url(docsrs))]
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")]
#[diagnostic(
code(miette::span_out_of_bounds),
@ -24,8 +25,9 @@ pub enum MietteError {
)]
OutOfBounds,
/// Returned when installing a [crate::ReportHandler] failed.
/// Typically, this will be because [crate::set_printer] was called twice.
/// Returned when installing a [`ReportHandler`](crate::ReportHandler)
/// failed. Typically, this will be because [`set_hook`](crate::set_hook)
/// was called twice.
#[error("Failed to install ReportHandler")]
#[diagnostic(code(miette::set_printer_failed), url(docsrs))]
SetPrinterFailure,

View File

@ -50,8 +50,8 @@ impl Report {
/// #
/// # use ffi::{Input, Output};
/// #
/// use miette::{Report, Result};
/// use futures::stream::{Stream, StreamExt, TryStreamExt};
/// use miette::{Report, Result};
///
/// async fn demo<S>(stream: S) -> Result<Vec<Output>>
/// where
@ -193,13 +193,13 @@ impl Report {
/// 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
/// [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:
/// For attaching a higher level error message to a `Result` as it is
/// 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:
pub fn wrap_err<D>(mut self, msg: D) -> Self
where
D: Display + Send + Sync + 'static,
@ -258,7 +258,7 @@ impl Report {
/// cause's cause etc.
///
/// 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) {
let mut chain = self.chain();
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.
///
/// For errors constructed from messages, this method returns true if `E` matches the type of
/// the message `D` **or** the type of the error on which the message has been attached. For
/// details about the interaction between message and downcasting, [see here].
/// For errors constructed from messages, this method returns true if `E`
/// matches the type of the message `D` **or** the type of the error on
/// 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
pub fn is<E>(&self) -> bool

View File

@ -2,19 +2,20 @@ use thiserror::Error;
use crate::{Diagnostic, Report};
/// Convenience [Diagnostic] that can be used as an "anonymous" wrapper for
/// Errors. This is intended to be paired with [IntoDiagnostic].
/// Convenience [`Diagnostic`] that can be used as an "anonymous" wrapper for
/// Errors. This is intended to be paired with [`IntoDiagnostic`].
#[derive(Debug, Error)]
#[error(transparent)]
struct DiagnosticError(Box<dyn std::error::Error + Send + Sync + 'static>);
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> {
/// Converts [Result]-like types that return regular errors into a
/// `Result` that returns a [Diagnostic].
/// Converts [`Result`]-like types that return regular errors into a
/// `Result` that returns a [`Diagnostic`].
fn into_diagnostic(self) -> Result<T, Report>;
}

View File

@ -54,7 +54,8 @@ type ErrorHook =
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)]
pub struct InstallError;
@ -139,9 +140,9 @@ pub trait ReportHandler: core::any::Any + Send + Sync {
/// # Example
///
/// ```rust
/// use indenter::indented;
/// use miette::Diagnostic;
/// use miette::ReportHandler;
/// use indenter::indented;
///
/// pub struct Handler;
///
@ -193,8 +194,9 @@ pub trait ReportHandler: core::any::Any + Send + Sync {
/// type alias for `Result<T, Report>`
///
/// This is a reasonable return type to use throughout your application but also for `fn main`; if
/// you do, failures will be printed along with a backtrace if one was captured.
/// This is a reasonable return type to use throughout your application but also
/// 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.
///
@ -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>`)
///
/// Due to restrictions for coherence `Report` cannot impl `From` for types that don't impl
/// `Error`. Attempts to do so will give "this type might implement Error in the future" as an
/// error. As such, `wrap_err`, which uses `From` under the hood, cannot be used to wrap these
/// types. Instead we encourage you to use the combinators provided for `Result` in `std`/`core`.
/// Due to restrictions for coherence `Report` cannot impl `From` for types that
/// don't impl `Error`. Attempts to do so will give "this type might implement
/// Error in the future" as an error. As such, `wrap_err`, which uses `From`
/// 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:
///
@ -309,18 +312,19 @@ pub type Result<T, E = Report> = core::result::Result<T, E>;
/// We encourage you to write this:
///
/// ```rust
/// use miette::{miette, Report, WrapErr};
/// use std::error::Error;
/// use miette::{WrapErr, Report, miette};
///
/// 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
///
/// After attaching a message of type `D` onto an error of type `E`, the resulting
/// `miette::Error` may be downcast to `D` **or** to `E`.
/// After attaching a message of type `D` onto an error of type `E`, the
/// resulting `miette::Error` may be downcast to `D` **or** to `E`.
///
/// That is, in codebases that rely on downcasting, miette's wrap_err supports
/// 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.**
///
/// 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
/// break existing working downcasts. In miette, any downcast that worked
/// before adding the message will continue to work after you add a message, so
/// you should freely wrap errors wherever it would be helpful.
/// be risky to introduce messages to existing code because new message
/// might break existing working downcasts. In miette, any downcast that
/// worked before adding the message will continue to work after you add a
/// message, so you should freely wrap errors wherever it would be helpful.
///
/// ```
/// # use miette::bail;

View File

@ -11,7 +11,7 @@ use crate::ThemeCharacters;
use crate::ThemeStyles;
/**
Create a custom [MietteHandler] from options.
Create a custom [`MietteHandler`] from options.
## Example
@ -43,7 +43,7 @@ pub struct MietteHandlerOpts {
}
impl MietteHandlerOpts {
/// Create a new [MietteHandlerOpts].
/// Create a new `MietteHandlerOpts`.
pub fn new() -> Self {
Default::default()
}
@ -56,15 +56,16 @@ impl MietteHandlerOpts {
self
}
/// Set a graphical theme for the handler when rendering in graphical
/// mode. Use [MietteHandlerOpts::force_graphical] to force graphical
/// mode. This option overrides [MietteHandlerOpts::color].
/// Set a graphical theme for the handler when rendering in graphical mode.
/// Use [`force_graphical()`](`MietteHandlerOpts::force_graphical) to force
/// graphical mode. This option overrides
/// [`color()`](`MietteHandlerOpts::color).
pub fn graphical_theme(mut self, theme: GraphicalTheme) -> Self {
self.theme = Some(theme);
self
}
/// Sets the width to wrap the report at. Defaults
/// Sets the width to wrap the report at. Defaults to 80.
pub fn width(mut self, width: usize) -> Self {
self.width = Some(width);
self
@ -126,7 +127,7 @@ impl MietteHandlerOpts {
self
}
/// Builds a [MietteHandler] from this builder.
/// Builds a [`MietteHandler`] from this builder.
pub fn build(self) -> MietteHandler {
let graphical = self.is_graphical();
let width = self.get_width();
@ -216,15 +217,18 @@ impl MietteHandlerOpts {
}
/**
A [ReportHandler] that displays a given [crate::Report] in a quasi-graphical
way, using terminal colors, unicode drawing characters, and other such things.
A [`ReportHandler`] that displays a given [`Report`](crate::Report) in a
quasi-graphical way, using terminal colors, unicode drawing characters, and
other such things.
This is the default reporter bundled with `miette`.
This printer can be customized by using `new_themed()` and handing it a
[GraphicalTheme] of your own creation (or using one of its own defaults!)
This printer can be customized by using
[`GraphicalReportHandler::new_themed()`] and handing it a [`GraphicalTheme`] of
your own creation (or using one of its own defaults).
See [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)]
pub struct MietteHandler {
@ -232,7 +236,7 @@ pub struct MietteHandler {
}
impl MietteHandler {
/// Creates a new [MietteHandler] with default settings.
/// Creates a new [`MietteHandler`] with default settings.
pub fn new() -> Self {
Default::default()
}

View File

@ -3,7 +3,7 @@ use std::fmt;
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
non-graphical environments, such as non-TTY output.
*/
@ -11,8 +11,8 @@ non-graphical environments, such as non-TTY output.
pub struct DebugReportHandler;
impl DebugReportHandler {
/// Create a new [NarratableReportHandler]. There are no customization
/// options.
/// Create a new [`NarratableReportHandler`](crate::NarratableReportHandler)
/// There are no customization options.
pub fn new() -> Self {
Self
}
@ -25,10 +25,9 @@ impl Default for DebugReportHandler {
}
impl DebugReportHandler {
/// Render a [Diagnostic]. This function is mostly internal and meant to
/// be called by the toplevel [ReportHandler] handler, but is
/// made public to make it easier (possible) to test in isolation from
/// global state.
/// Render a [`Diagnostic`]. This function is mostly internal and meant to
/// 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(
&self,
f: &mut fmt::Formatter<'_>,

View File

@ -8,15 +8,17 @@ use crate::protocol::{Diagnostic, Severity};
use crate::{LabeledSpan, MietteError, ReportHandler, SourceCode, SourceSpan, SpanContents};
/**
A [ReportHandler] that displays a given [crate::Report] in a quasi-graphical
way, using terminal colors, unicode drawing characters, and other such things.
A [`ReportHandler`] that displays a given [`Report`](crate::Report) in a
quasi-graphical way, using terminal colors, unicode drawing characters, and
other such things.
This is the default reporter bundled with `miette`.
This printer can be customized by using `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)]
pub struct GraphicalReportHandler {
@ -29,8 +31,8 @@ pub struct GraphicalReportHandler {
}
impl GraphicalReportHandler {
/// Create a new [GraphicalReportHandler] with the default
/// [GraphicalTheme]. This will use both unicode characters and colors.
/// Create a new `GraphicalReportHandler` with the default
/// [`GraphicalTheme`]. This will use both unicode characters and colors.
pub fn new() -> Self {
Self {
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 {
Self {
linkify_code: true,
@ -60,7 +62,7 @@ impl GraphicalReportHandler {
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 {
self.linkify_code = links;
self
@ -78,7 +80,7 @@ impl GraphicalReportHandler {
self
}
/// Sets the "global" footer for this handler.
/// Sets the 'global' footer for this handler.
pub fn with_footer(mut self, footer: String) -> Self {
self.footer = Some(footer);
self
@ -98,10 +100,9 @@ impl Default for GraphicalReportHandler {
}
impl GraphicalReportHandler {
/// Render a [Diagnostic]. This function is mostly internal and meant to
/// be called by the toplevel [ReportHandler] handler, but is
/// made public to make it easier (possible) to test in isolation from
/// global state.
/// Render a [`Diagnostic`]. This function is mostly internal and meant to
/// 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(
&self,
f: &mut impl fmt::Write,
@ -294,8 +295,8 @@ impl GraphicalReportHandler {
{
contexts.pop();
contexts.push((
new_span, // We'll throw this away later
left_conts,
// We'll throw this away later
new_span, left_conts,
));
} else {
contexts.push((right, right_conts));
@ -346,7 +347,8 @@ impl GraphicalReportHandler {
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[..]
.last()
.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 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 tabs_as_spaces = tab_count * w - tab_count;
hl.offset() - line.offset + tabs_as_spaces
@ -610,7 +613,8 @@ impl GraphicalReportHandler {
.iter()
.map(|hl| {
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 tabs_as_spaces = tab_count * w - tab_count;
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)
}
// 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
// calculate gutters.
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
// ...and it stops after this line's end.
&& span.offset() + span.len() > self.offset + self.length

View File

@ -3,14 +3,13 @@ use std::fmt::{self, Write};
use crate::{protocol::Diagnostic, ReportHandler, Severity, SourceCode};
/**
[ReportHandler] that renders json output.
It's a machine-readable output.
[`ReportHandler`] that renders JSON output. It's a machine-readable output.
*/
#[derive(Debug, Clone)]
pub struct JSONReportHandler;
impl JSONReportHandler {
/// Create a new [JSONReportHandler]. There are no customization
/// Create a new [`JSONReportHandler`]. There are no customization
/// options.
pub fn new() -> Self {
Self
@ -54,10 +53,9 @@ fn escape(input: &'_ str) -> Escape<'_> {
}
impl JSONReportHandler {
/// Render a [Diagnostic]. This function is mostly internal and meant to
/// be called by the toplevel [ReportHandler] handler, but is
/// made public to make it easier (possible) to test in isolation from
/// global state.
/// Render a [`Diagnostic`]. This function is mostly internal and meant to
/// 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(
&self,
f: &mut impl fmt::Write,

View File

@ -7,7 +7,7 @@ use crate::protocol::{Diagnostic, Severity};
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
non-graphical environments, such as non-TTY output.
*/
@ -18,7 +18,7 @@ pub struct NarratableReportHandler {
}
impl NarratableReportHandler {
/// Create a new [NarratableReportHandler]. There are no customization
/// Create a new [`NarratableReportHandler`]. There are no customization
/// options.
pub fn new() -> Self {
Self {
@ -47,8 +47,8 @@ impl Default for NarratableReportHandler {
}
impl NarratableReportHandler {
/// Render a [Diagnostic]. This function is mostly internal and meant to
/// be called by the toplevel [ReportHandler] handler, but is
/// Render a [`Diagnostic`]. This function is mostly internal and meant to
/// 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(
@ -345,7 +345,8 @@ enum SpanAttach {
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 {
let mut column = text.get(0..offset).map(|s| s.width()).unwrap_or_else(|| {
let mut column = 0;

View File

@ -2,10 +2,12 @@ use atty::Stream;
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,
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
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 {
Self {
characters: ThemeCharacters::unicode(),
@ -95,7 +98,7 @@ fn style() -> Style {
impl ThemeStyles {
/// Nice RGB colors.
/// Credit: http://terminal.sexy/#FRUV0NDQFRUVrEFCkKlZ9L91ap-1qnWfdbWq0NDQUFBQrEFCkKlZ9L91ap-1qnWfdbWq9fX1
/// [Credit](http://terminal.sexy/#FRUV0NDQFRUVrEFCkKlZ9L91ap-1qnWfdbWq0NDQUFBQrEFCkKlZ9L91ap-1qnWfdbWq9fX1).
pub fn rgb() -> Self {
Self {
error: style().fg_rgb::<255, 30, 30>(),
@ -143,11 +146,12 @@ 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::GraphicalReportHandler].
/// Characters to be used when drawing when using
/// [crate::GraphicalReportHandler].
#[allow(missing_docs)]
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct ThemeCharacters {

View File

@ -1,8 +1,8 @@
use crate::{MietteError, MietteSpanContents, SourceCode, SpanContents};
/// Utility struct for when you have a regular [Source] type, such as a String,
/// that doesn't implement `name`, or if you want to override the `.name()`
/// returned by the `Source`.
/// Utility struct for when you have a regular [`SourceCode`] type, such as a
/// String, that doesn't implement `name`, or if you want to override the
/// `.name()` returned by the `SourceCode`.
pub struct NamedSource {
source: Box<dyn SourceCode + 'static>,
name: String,
@ -18,7 +18,8 @@ impl std::fmt::Debug for 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 {
Self {
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) {
&*self.source
}

View File

@ -1,9 +1,8 @@
/*!
This module defines the core of the miette protocol: a series of types and traits
that you can implement to get access to miette's (and related library's) full
reporting and such features.
This module defines the core of the miette protocol: a series of types and
traits 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,
@ -12,50 +11,51 @@ use std::{
use crate::MietteError;
/**
Adds rich metadata to your Error that can be used by [Report] to print
really nice and human-friendly error messages.
*/
/// Adds rich metadata to your Error that can be used by
/// [`Report`](crate::Report) to print really nice and human-friendly error
/// messages.
pub trait Diagnostic: std::error::Error {
/// Unique diagnostic code that can be used to look up more information
/// about this Diagnostic. Ideally also globally unique, and documented in
/// the toplevel crate's documentation for easy searching. Rust path
/// about this `Diagnostic`. Ideally also globally unique, and documented
/// in the toplevel crate's documentation for easy searching. Rust path
/// 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>> {
None
}
/// Diagnostic severity. This may be used by [ReportHandler]s to change the
/// display format of this diagnostic.
/// Diagnostic severity. This may be used by
/// [`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> {
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?
fn help<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
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>> {
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> {
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> + '_>> {
None
}
/// Additional related Diagnostics.
/// Additional related `Diagnostic`s.
fn related<'a>(&'a self) -> Option<Box<dyn Iterator<Item = &'a dyn Diagnostic> + 'a>> {
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
way different Diagnostics are displayed.
[`Diagnostic`] severity. Intended to be used by
[`ReportHandler`](crate::ReportHandler)s to change the way different
[`Diagnostic`]s are displayed.
*/
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum Severity {
@ -169,13 +170,13 @@ pub enum Severity {
/**
Represents readable source code of some sort.
This trait is able to support simple Source types like [String]s, as well
as more involved types like indexes into centralized `SourceMap`-like types,
file handles, and even network streams.
This trait is able to support simple `SourceCode` types like [`String`]s, as
well as more involved types like indexes into centralized `SourceMap`-like
types, file handles, and even network streams.
If you can read it, you can source it,
and it's not necessary to read the whole thing--meaning you should be able to
support SourceCodes which are gigabytes or larger in size.
If you can read it, you can source it, and it's not necessary to read the
whole thing--meaning you should be able to support `SourceCode`s which are
gigabytes or larger in size.
*/
pub trait SourceCode: Send + Sync {
/// 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>;
}
/**
A labeled [SourceSpan].
*/
/// A labeled [`SourceSpan`].
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct LabeledSpan {
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> {
self.label.as_deref()
}
/// Returns a reference to the inner [SourceSpan].
/// Returns a reference to the inner [`SourceSpan`].
pub fn inner(&self) -> &SourceSpan {
&self.span
}
@ -229,52 +228,53 @@ impl LabeledSpan {
self.span.offset()
}
/// Returns the number of bytes this LabeledSpan spans.
/// Returns the number of bytes this `LabeledSpan` spans.
pub fn len(&self) -> usize {
self.span.len()
}
/// True if this LabeledSpan is empty.
/// True if this `LabeledSpan` is empty.
pub fn is_empty(&self) -> bool {
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.
*/
pub trait SpanContents<'a> {
/// Reference to the data inside the associated span, in bytes.
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;
/// 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> {
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;
/// The 0-indexed column in the associated [SourceCode] where the data begins,
/// relative to `line`.
/// The 0-indexed column in the associated [`SourceCode`] where the data
/// begins, relative to `line`.
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;
}
/**
Basic implementation of the [SpanContents] trait, for convenience.
Basic implementation of the [`SpanContents`] trait, for convenience.
*/
#[derive(Clone, Debug)]
pub struct MietteSpanContents<'a> {
// Data from a [SourceCode], in bytes.
// Data from a [`SourceCode`], in bytes.
data: &'a [u8],
// span actually covered by this SpanContents.
span: SourceSpan,
// The 0-indexed line where the associated [SourceSpan] _starts_.
// The 0-indexed line where the associated [`SourceSpan`] _starts_.
line: usize,
// The 0-indexed column where the associated [SourceSpan] _starts_.
// The 0-indexed column where the associated [`SourceSpan`] _starts_.
column: usize,
// Number of line in this snippet.
line_count: usize,
@ -283,7 +283,7 @@ pub struct MietteSpanContents<'a> {
}
impl<'a> MietteSpanContents<'a> {
/// Make a new [MietteSpanContents] object.
/// Make a new [`MietteSpanContents`] object.
pub fn new(
data: &'a [u8],
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(
name: String,
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)]
pub struct SourceSpan {
@ -354,7 +354,7 @@ pub struct SourceSpan {
}
impl SourceSpan {
/// Create a new [SourceSpan].
/// Create a new [`SourceSpan`].
pub fn new(start: SourceOffset, length: SourceOffset) -> Self {
Self {
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 {
self.offset.offset()
}
/// Total length of the [SourceSpan], in bytes.
/// Total length of the [`SourceSpan`], in bytes.
pub fn len(&self) -> usize {
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.
pub fn is_empty(&self) -> bool {
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;
/**
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)]
pub struct SourceOffset(ByteOffset);
@ -453,7 +453,7 @@ impl SourceOffset {
/// 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
/// as a SourceOffset
/// as a [`SourceOffset`].
///
/// 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

View File

@ -1,5 +1,5 @@
/*!
Default trait implementations for [SourceCode].
Default trait implementations for [`SourceCode`].
*/
use std::{
borrow::{Cow, ToOwned},
@ -172,8 +172,11 @@ impl<T: SourceCode> SourceCode for Arc<T> {
impl<T: ?Sized + SourceCode + ToOwned> SourceCode for Cow<'_, T>
where
// The minimal bounds are used here. `T::Owned` need not be `SourceCode`,
// because `&T` can always be obtained from `Cow<'_, T>`.
// The minimal bounds are used here.
// `T::Owned` need not be
// `SourceCode`, because `&T`
// can always be obtained from
// `Cow<'_, T>`.
T::Owned: Debug + Send + Sync,
{
fn read_span<'a>(

View File

@ -652,7 +652,8 @@ fn multiple_multiline_highlights_adjacent() -> Result<(), MietteError> {
}
#[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]
/// Lines are overlapping, but the offsets themselves aren't, so they _look_
/// disjunct if you only look at offsets.

View File

@ -481,7 +481,8 @@ diagnostic code: oops::my::bad
}
#[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]
/// Lines are overlapping, but the offsets themselves aren't, so they _look_
/// disjunct if you only look at offsets.