diff --git a/README.md b/README.md index 56e80be..d92d8fa 100644 --- a/README.md +++ b/README.md @@ -200,7 +200,17 @@ This crate does its best to be usable as a drop in replacement of `anyhow` and vice-versa by `re-exporting` all of the renamed APIs with the names used in `anyhow`, though there are some differences still. -#### `Context` and `Option` +### Disabling the compatibility layer + +The `anyhow` compatibility layer is enabled by default. +If you do not need anyhow compatibility, it is advisable +to disable the `"anyhow"` feature: + +```toml +eyre = { version = "0.6", default-features = false, features = ["auto-install", "track-caller"] } +``` + +### `Context` and `Option` As part of renaming `Context` to `WrapErr` we also intentionally do not implement `WrapErr` for `Option`. This decision was made because `wrap_err` diff --git a/eyre/CHANGELOG.md b/eyre/CHANGELOG.md index 14136b4..4183085 100644 --- a/eyre/CHANGELOG.md +++ b/eyre/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] - ReleaseDate +### Added +- feature flag for `anyhow` compatibility traits [by LeoniePhiline](https://github.com/eyre-rs/eyre/pull/138) ## [0.6.11] - 2023-12-13 ### Fixed diff --git a/eyre/Cargo.toml b/eyre/Cargo.toml index 4b01774..1085cbb 100644 --- a/eyre/Cargo.toml +++ b/eyre/Cargo.toml @@ -13,7 +13,8 @@ readme = { workspace = true } rust-version = { workspace = true } [features] -default = ["auto-install", "track-caller"] +default = ["anyhow", "auto-install", "track-caller"] +anyhow = [] auto-install = [] track-caller = [] diff --git a/eyre/src/context.rs b/eyre/src/context.rs index a15b41b..aaba5bd 100644 --- a/eyre/src/context.rs +++ b/eyre/src/context.rs @@ -1,5 +1,5 @@ use crate::error::{ContextError, ErrorImpl}; -use crate::{ContextCompat, Report, StdError, WrapErr}; +use crate::{Report, StdError, WrapErr}; use core::fmt::{self, Debug, Display, Write}; #[cfg(backtrace)] @@ -62,6 +62,7 @@ where } } + #[cfg(feature = "anyhow")] fn context(self, msg: D) -> Result where D: Display + Send + Sync + 'static, @@ -69,6 +70,7 @@ where self.wrap_err(msg) } + #[cfg(feature = "anyhow")] fn with_context(self, msg: F) -> Result where D: Display + Send + Sync + 'static, @@ -78,7 +80,8 @@ where } } -impl ContextCompat for Option { +#[cfg(feature = "anyhow")] +impl crate::ContextCompat for Option { fn wrap_err(self, msg: D) -> Result where D: Display + Send + Sync + 'static, diff --git a/eyre/src/error.rs b/eyre/src/error.rs index 5a3d2d8..d6e3d5d 100644 --- a/eyre/src/error.rs +++ b/eyre/src/error.rs @@ -116,6 +116,7 @@ impl Report { unsafe { Report::construct(error, vtable, handler) } } + #[cfg(feature = "anyhow")] #[cfg_attr(track_caller, track_caller)] pub(crate) fn from_display(message: M) -> Self where diff --git a/eyre/src/lib.rs b/eyre/src/lib.rs index f26c6c8..33c60d3 100644 --- a/eyre/src/lib.rs +++ b/eyre/src/lib.rs @@ -265,7 +265,17 @@ //! vice-versa by re-exporting all of the renamed APIs with the names used in //! `anyhow`, though there are some differences still. //! -//! #### `Context` and `Option` +//! ### Disabling the compatibility layer +//! +//! The `anyhow` compatibility layer is enabled by default. +//! If you do not need anyhow compatibility, it is advisable +//! to disable the `"anyhow"` feature: +//! +//! ```toml +//! eyre = { version = "0.6", default-features = false, features = ["auto-install", "track-caller"] } +//! ``` +//! +//! ### `Context` and `Option` //! //! As part of renaming `Context` to `WrapErr` we also intentionally do not //! implement `WrapErr` for `Option`. This decision was made because `wrap_err` @@ -375,18 +385,23 @@ use std::error::Error as StdError; pub use eyre as format_err; /// Compatibility re-export of `eyre` for interop with `anyhow` +#[cfg(feature = "anyhow")] pub use eyre as anyhow; use once_cell::sync::OnceCell; use ptr::OwnedPtr; +#[cfg(feature = "anyhow")] #[doc(hidden)] pub use DefaultHandler as DefaultContext; +#[cfg(feature = "anyhow")] #[doc(hidden)] pub use EyreHandler as EyreContext; #[doc(hidden)] pub use Report as ErrReport; /// Compatibility re-export of `Report` for interop with `anyhow` +#[cfg(feature = "anyhow")] pub use Report as Error; /// Compatibility re-export of `WrapErr` for interop with `anyhow` +#[cfg(feature = "anyhow")] pub use WrapErr as Context; /// The core error reporting type of the library, a wrapper around a dynamic error reporting type. @@ -1112,12 +1127,14 @@ pub trait WrapErr: context::private::Sealed { F: FnOnce() -> D; /// Compatibility re-export of wrap_err for interop with `anyhow` + #[cfg(feature = "anyhow")] #[cfg_attr(track_caller, track_caller)] fn context(self, msg: D) -> Result where D: Display + Send + Sync + 'static; /// Compatibility re-export of wrap_err_with for interop with `anyhow` + #[cfg(feature = "anyhow")] #[cfg_attr(track_caller, track_caller)] fn with_context(self, f: F) -> Result where @@ -1223,6 +1240,7 @@ pub trait OptionExt: context::private::Sealed { /// .ok_or_else(|| eyre!("the thing wasnt in the list")) /// } /// ``` +#[cfg(feature = "anyhow")] pub trait ContextCompat: context::private::Sealed { /// Compatibility version of `wrap_err` for creating new errors with new source on `Option` /// when porting from `anyhow` diff --git a/eyre/tests/test_context_access.rs b/eyre/tests/test_context_access.rs index 54e3da4..0971a0f 100644 --- a/eyre/tests/test_context_access.rs +++ b/eyre/tests/test_context_access.rs @@ -1,3 +1,5 @@ +#![cfg(feature = "anyhow")] + mod common; use crate::common::maybe_install_handler; diff --git a/eyre/tests/test_location.rs b/eyre/tests/test_location.rs index 766514a..53c181f 100644 --- a/eyre/tests/test_location.rs +++ b/eyre/tests/test_location.rs @@ -1,6 +1,6 @@ use std::panic::Location; -use eyre::{OptionExt as _, WrapErr}; +use eyre::WrapErr; struct LocationHandler { actual: Option<&'static str>, @@ -83,6 +83,7 @@ fn test_wrap_err_with() { println!("{:?}", err); } +#[cfg(feature = "anyhow")] #[test] fn test_option_ok_or_eyre() { let _ = eyre::set_hook(Box::new(|_e| { @@ -90,12 +91,14 @@ fn test_option_ok_or_eyre() { Box::new(LocationHandler::new(expected_location)) })); + use eyre::OptionExt; let err = None::<()>.ok_or_eyre("oopsie").unwrap_err(); // should panic if the location isn't in our crate println!("{:?}", err); } +#[cfg(feature = "anyhow")] #[test] fn test_context() { let _ = eyre::set_hook(Box::new(|_e| { @@ -111,6 +114,7 @@ fn test_context() { println!("{:?}", err); } +#[cfg(feature = "anyhow")] #[test] fn test_with_context() { let _ = eyre::set_hook(Box::new(|_e| { @@ -126,6 +130,7 @@ fn test_with_context() { println!("{:?}", err); } +#[cfg(feature = "anyhow")] #[test] fn test_option_compat_wrap_err() { let _ = eyre::set_hook(Box::new(|_e| { @@ -140,6 +145,7 @@ fn test_option_compat_wrap_err() { println!("{:?}", err); } +#[cfg(feature = "anyhow")] #[test] fn test_option_compat_wrap_err_with() { let _ = eyre::set_hook(Box::new(|_e| { @@ -154,6 +160,7 @@ fn test_option_compat_wrap_err_with() { println!("{:?}", err); } +#[cfg(feature = "anyhow")] #[test] fn test_option_compat_context() { let _ = eyre::set_hook(Box::new(|_e| { @@ -168,6 +175,7 @@ fn test_option_compat_context() { println!("{:?}", err); } +#[cfg(feature = "anyhow")] #[test] fn test_option_compat_with_context() { let _ = eyre::set_hook(Box::new(|_e| {