diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
commit | 26a029d407be480d791972afb5975cf62c9360a6 (patch) | |
tree | f435a8308119effd964b339f76abb83a57c29483 /third_party/rust/derive_more-impl/doc/error.md | |
parent | Initial commit. (diff) | |
download | firefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz firefox-26a029d407be480d791972afb5975cf62c9360a6.zip |
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/derive_more-impl/doc/error.md')
-rw-r--r-- | third_party/rust/derive_more-impl/doc/error.md | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/third_party/rust/derive_more-impl/doc/error.md b/third_party/rust/derive_more-impl/doc/error.md new file mode 100644 index 0000000000..20ff24cfe4 --- /dev/null +++ b/third_party/rust/derive_more-impl/doc/error.md @@ -0,0 +1,150 @@ +# Using `#[derive(Error)]` + +Deriving `Error` will generate an `Error` implementation, that contains +(depending on the type) a `source()` and a `provide()` method. Please note, +at the time of writing `provide()` is only supported on nightly rust. So you +have to use that to make use of it. + +For a struct, these methods always do the same. For an `enum` they have separate +behaviour for each of the variants. The variant is first matched and then the +implementation will do the same as it would have done if the variant was a +struct. + +Usually when you derive `Error` you will also want to [derive `Display`](crate::Display) and +often [`From` as well](crate::From). + + +### When and how does it derive `source()`? + +1. It's a struct/variant with named fields and one is the fields is + called `source`. Then it would return that field as the `source`. +2. It's a tuple struct/variant and there's exactly one field that is not used as + the `backtrace`. So either a tuple struct with one field, or one with two where one + is the `backtrace`. Then it returns this field as the `source`. +3. One of the fields is annotated with `#[error(source)]`. Then it would + return that field as the `source`. + +### When and how does it derive `provide()`? + +1. It's a struct/variant with named fields and one of the fields is + called `backtrace`. Then it would return that field as the `backtrace`. +2. It's a tuple struct/variant and the type of exactly one of the fields is + called `Backtrace`. Then it would return that field as the `backtrace`. +3. One of the fields is annotated with `#[error(backtrace)]`. Then it would + return that field as the `backtrace`. + +### Ignoring fields for derives + +It's possible to ignore a field or a whole enum variant completely for this +derive using the `#[error(ignore)]` attribute. This will ignore it both for +detecting `backtrace` and `source`. It's also possible to mark a field only +ignored for one of these methods by using `#[error(not(backtrace))]` or +`#[error(not(source))]`. + + +### What works in `no_std`? + +If you want to use the `Error` derive on `no_std` environments, then you need to +compile with nightly and enable this feature: +```ignore +#![feature(error_in_core)] +``` + +Backtraces don't work though, because the `Backtrace` type is only available in +`std`. + + + + +## Example usage + +```rust +# #![cfg_attr(nightly, feature(error_generic_member_access, provide_any))] +// Nightly requires enabling these features: +// #![feature(error_generic_member_access, provide_any)] +# #[cfg(not(nightly))] fn main() {} +# #[cfg(nightly)] fn main() { +# use std::{any, error::Error as _, backtrace::Backtrace}; +# +# use derive_more::{Display, Error, From}; + +// std::error::Error requires std::fmt::Debug and std::fmt::Display, +// so we can also use derive_more::Display for fully declarative +// error-type definitions. + +#[derive(Default, Debug, Display, Error)] +struct Simple; + +#[derive(Default, Debug, Display, Error)] +struct WithSource { + source: Simple, +} +#[derive(Default, Debug, Display, Error)] +struct WithExplicitSource { + #[error(source)] + explicit_source: Simple, +} + +#[derive(Default, Debug, Display, Error)] +struct Tuple(Simple); + +#[derive(Default, Debug, Display, Error)] +struct WithoutSource(#[error(not(source))] i32); + +#[derive(Debug, Display, Error)] +#[display("An error with a backtrace")] +struct WithSourceAndBacktrace { + source: Simple, + backtrace: Backtrace, +} + +// derive_more::From fits nicely into this pattern as well +#[derive(Debug, Display, Error, From)] +enum CompoundError { + Simple, + WithSource { + source: Simple, + }, + #[from(ignore)] + WithBacktraceFromSource { + #[error(backtrace)] + source: Simple, + }, + #[display("{source}")] + WithDifferentBacktrace { + source: Simple, + backtrace: Backtrace, + }, + WithExplicitSource { + #[error(source)] + explicit_source: WithSource, + }, + #[from(ignore)] + WithBacktraceFromExplicitSource { + #[error(backtrace, source)] + explicit_source: WithSource, + }, + Tuple(WithExplicitSource), + WithoutSource(#[error(not(source))] Tuple), +} + +assert!(Simple.source().is_none()); +assert!(any::request_ref::<Backtrace>(&Simple).is_none()); +assert!(WithSource::default().source().is_some()); +assert!(WithExplicitSource::default().source().is_some()); +assert!(Tuple::default().source().is_some()); +assert!(WithoutSource::default().source().is_none()); +let with_source_and_backtrace = WithSourceAndBacktrace { + source: Simple, + backtrace: Backtrace::capture(), +}; +assert!(with_source_and_backtrace.source().is_some()); +assert!(any::request_ref::<Backtrace>(&with_source_and_backtrace).is_some()); + +assert!(CompoundError::Simple.source().is_none()); +assert!(CompoundError::from(Simple).source().is_some()); +assert!(CompoundError::from(WithSource::default()).source().is_some()); +assert!(CompoundError::from(WithExplicitSource::default()).source().is_some()); +assert!(CompoundError::from(Tuple::default()).source().is_none()); +# } +``` |