[][src]Crate adhocerr

A library for the construction of efficient static/dynamic single use error types per callsite.

adhocerr = "0.1"


Creating a root cause error:

use adhocerr::err;

fn get_git_root(start: &Path) -> Result<PathBuf, impl Error + 'static> {
        .find(|a| a.join(".git").is_dir())
        .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"))


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.


The Expanded version of the example above would look like this:

fn get_git_root(start: &Path) -> Result<PathBuf, impl Error + 'static> {
        .find(|a| a.join(".git").is_dir())
            struct AdhocError;

            impl std::error::Error for AdhocError {
                fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {

            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")



pub use err as format_err;



Return an ad-hoc error immediately


Return early with an error if a condition is not satisfied.


Create an ad-hoc error type with zero size if none is needed


Thinly wrap an error by defining a hidden error type and returning a closure to construct it