This is the kind of macro that libraries like Oh, they do!
eyre should have.
On the other hand, it feels like macros like
bail!() (and perhaps this
ensure!()) should have been in the stdlib the whole time.
It also seems that
ensure!() is very related to
?, it's as if Rust's
? were too restricted and that's why we need additional macros. We already know what's the most generalized syntax for this: Haskell's do notation, but, is there a way to extend the power of
? without going all the way there?
This also seems very related to assertions, to the point where another name for this could be
ensure()! is a better name). Note that it's still useful to have both: assertions are used for fundamental assumptions, where the program can't possibly recover, and ensure just means that if the assumption is violated it's an error the caller could either handle or bubble up.
However, the most ergonomic way to write assertions (IMO) is using a macro like
contracts. I wonder if such attribute macro would be an useful companion for
#[ensure] is a bad name though (it doesn't distinguish between preconditions and postconditions, that is, calling
ensure!() at the beginning or at the end of the function)
Anyway, I like when the
Error type can be left implicit. In most error libraries this is done by
type Result<T> = std::result::Result<T, mylibrary::Error>; but there's at least one library where whatever
Error type in scope is chosen implicitly:
#[throws(Error)] and I think it is great. So perhaps
ensure!(condition) should mean
ensure!(condition, Error) for whatever
Error type that is in scope. The stdlib could provide a more structured way to say "this library has an error type that should be used implictly", but I think the fehler approach is good enough.
If there's a companion attribute macro, it would be nice if
Error could be left implicit there, too.