err-as-you-go

Crates.ioerr-as-you-go
lib.rserr-as-you-go
version0.1.3
sourcesrc
created_at2023-03-18 01:50:50.814096
updated_at2023-03-18 09:26:06.75956
descriptioneasy inline error types
homepage
repositoryhttps://github.com/aatifsyed/err-as-you-go
max_upload_size
id813460
size37,462
Aatif Syed (aatifsyed)

documentation

https://docs.rs/err-as-you-go

README

crates-io docs-rs github

err-as-you-go

Generate enum error types inline.

If you want:

  • to easy throw errors inline like with anyhow
  • to make your error types handleable in a nice enum like thiserror

then this is the crate for you!

use err_as_you_go::err_as_you_go;

#[err_as_you_go]
fn shave_yaks(
    num_yaks: usize,
    empty_buckets: usize,
    num_razors: usize,
) -> Result<(), ShaveYaksError> {
    if num_razors == 0 {
        return Err(err!(NotEnoughRazors));
    }
    if num_yaks > empty_buckets {
        return Err(err!(NotEnoughBuckets {
            got: usize = empty_buckets,
            required: usize = num_yaks,
        }));
    }
    Ok(())
}

Under the hood, a struct like this is generated:

enum ShaveYaksError { // name and visibility are taken from function return type and visibility
    NotEnoughRazors,
    NotEnoughBuckets {
        got: usize,
        required: usize,
    }
}

Importantly, you can derive on the generated struct, and passthrough attributes, allowing you to use crates like thiserror.


#[err_as_you_go(derive(Debug, thiserror::Error))]
fn shave_yaks(
    num_yaks: usize,
    empty_buckets: usize,
    num_razors: usize,
) -> Result<(), ShaveYaksError> {
    if num_razors == 0 {
        return Err(err!(
            #[error("not enough razors!")]
            NotEnoughRazors
        ));
    }
    if num_yaks > empty_buckets {
        return Err(err!(
            #[error("not enough buckets - needed {required}")]
            NotEnoughBuckets {
                got: usize = empty_buckets,
                required: usize = num_yaks,
            }
        ));
    }
    Ok(())
}

Which generates the following:

#[derive(Debug, thiserror::Error)]
enum ShaveYaksError {
    #[error("not enough razors!")]
    NotEnoughRazors,
    #[error("not enough buckets - needed {required}")]
    NotEnoughBuckets {
        got: usize,
        required: usize,
    }
}

And err! macro invocations are replaced with struct instantiations - no matter where they are in the function body!

If you need to reuse the same variant within a function, just use the normal construction syntax:

#[err_as_you_go]
fn foo() -> Result<(), FooError> {
    fallible_op().map_err(|e| err!(IoError(io::Error = e)));
    Err(FooError::IoError(todo!()))
}
Commit count: 31

cargo fmt