Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into feat-anyhow-compat
Browse files Browse the repository at this point in the history
  • Loading branch information
ten3roberts committed Dec 8, 2023
2 parents 1f860f7 + d5cad7c commit 9d8e124
Show file tree
Hide file tree
Showing 6 changed files with 153 additions and 37 deletions.
16 changes: 11 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,24 +208,30 @@ implies that you're creating a new error that saves the old error as its
`source`. With `Option` there is no source error to wrap, so `wrap_err` ends up
being somewhat meaningless.

Instead `eyre` intends for users to use the combinator functions provided by
`std` for converting `Option`s to `Result`s. So where you would write this with
Instead `eyre` offers [`OptionExt::ok_or_eyre`] to yield _static_ errors from `None`,
and intends for users to use the combinator functions provided by
`std`, converting `Option`s to `Result`s, for _dynamic_ errors.
So where you would write this with
anyhow:

[`OptionExt::ok_or_eyre`]: https://docs.rs/eyre/latest/eyre/trait.OptionExt.html#tymethod.ok_or_eyre

```rust
use anyhow::Context;

let opt: Option<()> = None;
let result = opt.context("new error message");
let result_static = opt.context("static error message");
let result_dynamic = opt.with_context(|| format!("{} error message", "dynamic"));
```

With `eyre` we want users to write:

```rust
use eyre::{eyre, Result};
use eyre::{eyre, OptionExt, Result};

let opt: Option<()> = None;
let result: Result<()> = opt.ok_or_else(|| eyre!("new error message"));
let result_static: Result<()> = opt.ok_or_eyre("static error message");
let result_dynamic: Result<()> = opt.ok_or_else(|| eyre!("{} error message", "dynamic"));
```

**NOTE**: However, to help with porting we do provide a `ContextCompat` trait which
Expand Down
69 changes: 45 additions & 24 deletions eyre/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,57 +8,78 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased] - ReleaseDate

## [0.6.10] - 2023-12-07
### Fixed
- stale references to `Error` in docstrings [by birkenfeld](https://github.com/eyre-rs/eyre/pull/87)

### Added
- one-argument ensure!($expr) [by sharnoff](https://github.com/eyre-rs/eyre/pull/86)
- documentation on the performance characteristics of `wrap_err` vs `wrap_err_with` [by akshayknarayan](https://github.com/eyre-rs/eyre/pull/93)
- tl;dr: `wrap_err_with` is faster unless the constructed error object already exists
- automated conversion to external errors for ensure! and bail! [by j-baker](https://github.com/eyre-rs/eyre/pull/95)
- eyre::Ok for generating eyre::Ok() without fully specifying the type [by kylewlacy](https://github.com/eyre-rs/eyre/pull/91)
- `OptionExt::ok_or_eyre` for yielding static `Report`s from `None` [by LeoniePhiline](https://github.com/eyre-rs/eyre/pull/125)

### New Contributors
- @sharnoff made their first contribution in https://github.com/eyre-rs/eyre/pull/86
- @akshayknarayan made their first contribution in https://github.com/eyre-rs/eyre/pull/93
- @j-baker made their first contribution in https://github.com/eyre-rs/eyre/pull/95
- @kylewlacy made their first contribution in https://github.com/eyre-rs/eyre/pull/91
- @LeoniePhiline made their first contribution in https://github.com/eyre-rs/eyre/pull/129

## [0.6.9] - 2023-11-17
### Fixed
- Fix stacked borrows when dropping [by TimDiekmann](https://github.com/eyre-rs/eyre/pull/81)
- Fix miri validation errors through now stricter provenance [by ten3roberts](https://github.com/eyre-rs/eyre/pull/103)
- Merge eyre related crates into monorepo [by pksunkara](https://github.com/eyre-rs/eyre/pull/104), [[2]](https://github.com/eyre-rs/eyre/pull/105)[[3]](https://github.com/eyre-rs/eyre/pull/107)
- Update documentation on no_std support [by thenorili](https://github.com/eyre-rs/eyre/pull/111)
- stacked borrows when dropping [by TimDiekmann](https://github.com/eyre-rs/eyre/pull/81)
- miri validation errors through now stricter provenance [by ten3roberts](https://github.com/eyre-rs/eyre/pull/103)
- documentation on no_std support [by thenorili](https://github.com/eyre-rs/eyre/pull/111)

### Added
- Add CONTRIBUTING.md [by yaahc](https://github.com/eyre-rs/eyre/pull/99)
- monorepo for eyre-related crates [by pksunkara](https://github.com/eyre-rs/eyre/pull/104), [[2]](https://github.com/eyre-rs/eyre/pull/105)[[3]](https://github.com/eyre-rs/eyre/pull/107)
- CONTRIBUTING.md [by yaahc](https://github.com/eyre-rs/eyre/pull/99)

## [0.6.8] - 2022-04-04
### Added
- Add `#[must_use]` to `Report`
- Add `must-install` feature to help reduce binary sizes when using a custom `EyreHandler`
- `#[must_use]` to `Report`
- `must-install` feature to help reduce binary sizes when using a custom `EyreHandler`

## [0.6.7] - 2022-02-24
### Fixed
- added missing track_caller annotation to new format arg capture constructor
- missing track_caller annotation to new format arg capture constructor

## [0.6.6] - 2022-01-19
### Added
- add support for format arguments capture on 1.58 and later
- support for format arguments capture on 1.58 and later

## [0.6.5] - 2021-01-05
### Added
- add optional support for converting into `pyo3` exceptions
- optional support for converting into `pyo3` exceptions

## [0.6.4] - 2021-01-04
### Fixed
- added missing track_caller annotations to `wrap_err` related trait methods
- missing track_caller annotations to `wrap_err` related trait methods

## [0.6.3] - 2020-11-10
### Fixed
- added missing track_caller annotation to autoref specialization functions
- missing track_caller annotation to autoref specialization functions

## [0.6.2] - 2020-10-27
### Fixed
- added missing track_caller annotation to new_adhoc function
- missing track_caller annotation to new_adhoc function

## [0.6.1] - 2020-09-28
### Added
- support track_caller on rust versions where it is available
- support for track_caller on rust versions where it is available


<!-- next-url -->
[Unreleased]: https://github.com/eyre-rs/eyre/compare/v0.6.9...HEAD
[0.6.9]: https://github.com/eyre-rs/eyre/compare/v0.6.8...v0.6.9
[0.6.8]: https://github.com/eyre-rs/eyre/compare/v0.6.7...v0.6.8
[0.6.7]: https://github.com/eyre-rs/eyre/compare/v0.6.6...v0.6.7
[0.6.6]: https://github.com/eyre-rs/eyre/compare/v0.6.5...v0.6.6
[0.6.5]: https://github.com/eyre-rs/eyre/compare/v0.6.4...v0.6.5
[0.6.4]: https://github.com/eyre-rs/eyre/compare/v0.6.3...v0.6.4
[0.6.3]: https://github.com/eyre-rs/eyre/compare/v0.6.2...v0.6.3
[0.6.2]: https://github.com/eyre-rs/eyre/compare/v0.6.1...v0.6.2
[0.6.1]: https://github.com/eyre-rs/eyre/releases/tag/v0.6.1
[Unreleased]: https://github.com/eyre-rs/eyre/compare/v0.6.10...HEAD
[0.6.10]: https://github.com/eyre-rs/eyre/compare/v0.6.9...v0.6.10
[0.6.9]: https://github.com/eyre-rs/eyre/compare/v0.6.8...v0.6.9
[0.6.8]: https://github.com/eyre-rs/eyre/compare/v0.6.7...v0.6.8
[0.6.7]: https://github.com/eyre-rs/eyre/compare/v0.6.6...v0.6.7
[0.6.6]: https://github.com/eyre-rs/eyre/compare/v0.6.5...v0.6.6
[0.6.5]: https://github.com/eyre-rs/eyre/compare/v0.6.4...v0.6.5
[0.6.4]: https://github.com/eyre-rs/eyre/compare/v0.6.3...v0.6.4
[0.6.3]: https://github.com/eyre-rs/eyre/compare/v0.6.2...v0.6.3
[0.6.2]: https://github.com/eyre-rs/eyre/compare/v0.6.1...v0.6.2
[0.6.1]: https://github.com/eyre-rs/eyre/releases/tag/v0.6.1
2 changes: 1 addition & 1 deletion eyre/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "eyre"
version = "0.6.9"
version = "0.6.10"
authors = ["David Tolnay <[email protected]>", "Jane Lusby <[email protected]>"]
description = "Flexible concrete Error Reporting type built on std::error::Error with customizable Reports"
documentation = "https://docs.rs/eyre"
Expand Down
74 changes: 67 additions & 7 deletions eyre/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,27 +273,31 @@
//! `source`. With `Option` there is no source error to wrap, so `wrap_err` ends up
//! being somewhat meaningless.
//!
//! Instead `eyre` intends for users to use the combinator functions provided by
//! `std` for converting `Option`s to `Result`s. So where you would write this with
//! Instead `eyre` offers [`OptionExt::ok_or_eyre`] to yield _static_ errors from `None`,
//! and intends for users to use the combinator functions provided by
//! `std`, converting `Option`s to `Result`s, for _dynamic_ errors.
//! So where you would write this with
//! anyhow:
//!
//! ```rust
//! use anyhow::Context;
//!
//! let opt: Option<()> = None;
//! let result = opt.context("new error message");
//! let result_static = opt.context("static error message");
//! let result_dynamic = opt.with_context(|| format!("{} error message", "dynamic"));
//! ```
//!
//! With `eyre` we want users to write:
//!
//! ```rust
//! use eyre::{eyre, Result};
//! use eyre::{eyre, OptionExt, Result};
//!
//! # #[cfg(not(feature = "auto-install"))]
//! # eyre::set_hook(Box::new(eyre::DefaultHandler::default_with)).unwrap();
//! #
//! let opt: Option<()> = None;
//! let result: Result<()> = opt.ok_or_else(|| eyre!("new error message"));
//! let result_static: Result<()> = opt.ok_or_eyre("static error message");
//! let result_dynamic: Result<()> = opt.ok_or_else(|| eyre!("{} error message", "dynamic"));
//! ```
//!
//! **NOTE**: However, to help with porting we do provide a `ContextCompat` trait which
Expand All @@ -314,7 +318,7 @@
//! [`simple-eyre`]: https://github.com/eyre-rs/simple-eyre
//! [`color-spantrace`]: https://github.com/eyre-rs/color-spantrace
//! [`color-backtrace`]: https://github.com/athre0z/color-backtrace
#![doc(html_root_url = "https://docs.rs/eyre/0.6.9")]
#![doc(html_root_url = "https://docs.rs/eyre/0.6.10")]
#![cfg_attr(
nightly,
feature(rustdoc_missing_doc_code_examples),
Expand Down Expand Up @@ -359,6 +363,7 @@ mod error;
mod fmt;
mod kind;
mod macros;
mod option;
mod ptr;
mod wrapper;

Expand All @@ -369,7 +374,7 @@ pub mod builder;
pub mod compat;
mod vtable;

use core::fmt::Display;
use core::fmt::{Debug, Display};

use std::error::Error as StdError;

Expand Down Expand Up @@ -1194,6 +1199,61 @@ pub trait WrapErr<T, E>: context::private::Sealed {
F: FnOnce() -> D;
}

/// Provides the [`ok_or_eyre`][OptionExt::ok_or_eyre] method for [`Option`].
///
/// This trait is sealed and cannot be implemented for types outside of
/// `eyre`.
///
/// # Example
///
/// ```
/// # #[cfg(not(feature = "auto-install"))]
/// # eyre::set_hook(Box::new(eyre::DefaultHandler::default_with)).unwrap();
/// use eyre::OptionExt;
///
/// let option: Option<()> = None;
///
/// let result = option.ok_or_eyre("static str error");
///
/// assert_eq!(result.unwrap_err().to_string(), "static str error");
/// ```
///
/// # `ok_or_eyre` vs `ok_or_else`
///
/// If string interpolation is required for the generated [report][Report],
/// use [`ok_or_else`][Option::ok_or_else] instead,
/// invoking [`eyre!`] to perform string interpolation:
///
/// ```
/// # #[cfg(not(feature = "auto-install"))]
/// # eyre::set_hook(Box::new(eyre::DefaultHandler::default_with)).unwrap();
/// use eyre::eyre;
///
/// let option: Option<()> = None;
///
/// let result = option.ok_or_else(|| eyre!("{} error", "dynamic"));
///
/// assert_eq!(result.unwrap_err().to_string(), "dynamic error");
/// ```
///
/// `ok_or_eyre` incurs no runtime cost, as the error object
/// is constructed from the provided static argument
/// only in the `None` case.
pub trait OptionExt<T>: context::private::Sealed {
/// Transform the [`Option<T>`] into a [`Result<T, E>`],
/// mapping [`Some(v)`][Option::Some] to [`Ok(v)`][Result::Ok]
/// and [`None`] to [`Report`].
///
/// `ok_or_eyre` allows for eyre [`Report`] error objects
/// to be lazily created from static messages in the `None` case.
///
/// For dynamic error messages, use [`ok_or_else`][Option::ok_or_else],
/// invoking [`eyre!`] in the closure to perform string interpolation.
fn ok_or_eyre<M>(self, message: M) -> crate::Result<T>
where
M: Debug + Display + Send + Sync + 'static;
}

/// Provides the `context` method for `Option` when porting from `anyhow`
///
/// This trait is sealed and cannot be implemented for types outside of
Expand Down
14 changes: 14 additions & 0 deletions eyre/src/option.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use crate::OptionExt;
use core::fmt::{Debug, Display};

impl<T> OptionExt<T> for Option<T> {
fn ok_or_eyre<M>(self, message: M) -> crate::Result<T>
where
M: Debug + Display + Send + Sync + 'static,
{
match self {
Some(ok) => Ok(ok),
None => Err(crate::Report::msg(message)),
}
}
}
15 changes: 15 additions & 0 deletions eyre/tests/test_option.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
mod common;

use self::common::maybe_install_handler;
use eyre::OptionExt;

#[test]
fn test_option_ok_or_eyre() {
maybe_install_handler().unwrap();

let option: Option<()> = None;

let result = option.ok_or_eyre("static str error");

assert_eq!(result.unwrap_err().to_string(), "static str error");
}

0 comments on commit 9d8e124

Please sign in to comment.