[−][src]Crate adhocerr
A library for the construction of efficient static/dynamic single use error types per callsite.
[dependencies]
adhocerr = "0.1"
Examples
Creating a root cause error:
use adhocerr::err; fn get_git_root(start: &Path) -> Result<PathBuf, impl Error + 'static> { start .ancestors() .find(|a| a.join(".git").is_dir()) .map(Path::to_owned) .ok_or(err!("Unable to find .git/ in parent directories")) }
Wrapping another Error:
use adhocerr::wrap; fn record_success() -> Result<(), impl Error + 'static> { std::fs::write(".success", "true").map_err(wrap!("Failed to save results of script")) }
Details
This crate provides two primary macros. err!
and wrap!
. The former, err!
, is used to
create ad-hoc error types without a root cause from strings. wrap!
on the other hand is used
to create new errors with a source member.
Both of these macros have two versions, and they generate completely different code, depending
on whether or not string interopoation (format!
-like code) is used in the error message. When
the error message is a fixed string, the macro declares a new struct in line that has the
string itself inserted into its Display
implementation. This way no memory is used or
allocations made to hold the error when they are not needed.
For err!
this means that your error type is a Zero Sized Type (ZST), for
wrap!
this means that your Wrapper error is the same size as the original
error you're wrapping.
When runtime interpolation is used and a String
allocation is necessary it
uses pre defined Error types to wrap the String to avoid declaring new types
unnecessarily, but hides them behind an impl Trait boundary.
Expanded
The Expanded version of the example above would look like this:
fn get_git_root(start: &Path) -> Result<PathBuf, impl Error + 'static> { start .ancestors() .find(|a| a.join(".git").is_dir()) .map(Path::to_owned) .ok_or({ #[derive(Debug)] struct AdhocError; impl std::error::Error for AdhocError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None } } impl core::fmt::Display for AdhocError { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.write_str("Unable to find .git/ in parent directories") } } AdhocError }) }
Re-exports
pub use err as format_err; |
Macros
bail | Return an ad-hoc error immediately |
ensure | Return early with an error if a condition is not satisfied. |
err | Create an ad-hoc error type with zero size if none is needed |
wrap | Thinly wrap an error by defining a hidden error type and returning a closure to construct it |