[−][src]Crate tear
Typed early returns and syntax sugar macros for try!-like error handling
Works with Rust v1.34+
Description
This crate exports the tear!
and rip!
macros.
tear!
is used with ValRet
for typed early returns. rip!
is syntax-sugar for try!
or the ?
operator.
Usage
// Add this in your crate entrypoint (main.rs or lib.rs) #[macro_use] extern crate tear; // Import symbols for this example, generally not needed use tear::prelude::*; // Error handling. Turn this… let x = can_error().map_err(rescue_error)?; // …into this let x = rip! { can_error() => rescue_error }; // Early return fn divide(a: i32, b: i32) -> Option<f32> { tear_if! { b == 0, None }; let quotient = (a as f32) / (b as f32); Some(quotient) } // This function tells the calling function to return early fn return_from_function() -> ValRet<String, i32> { Ret(-1) } // Action at a distance fn status_code() -> i32 { tear! { return_from_function() }; // returns 0 }
See the documentation for tear!
and rip!
for more examples.
Rationale
I wanted to make early returns more explicit.
if $cond {
$statements;
return $ret;
}
Normally, you can't tell from the outside if a code block will return early or not.
To bring the return statement out of the block requires a way to signal that we want to return early and something to catch that signal.
ValRet
represents the signal and tear!
returns early if needed.
Having a typed early return allows you to have functions that can force the caller function to return early. Action at a distance inspired by how Slips work in Raku.
After reading up on how the ?
operator works, I thought of leveraging this typed early return for an explicit error handling syntax.
I wanted to annotate each potential failure point with a symbol and associate that symbol to an error handler.
Something like this:
let path = find_config_file().mark(A)
let mut file = get_file_bufwriter(&path).mark(B)
// Error handlers
[A]: .ok_or(Error::FindPathF)?;
[B]: .map_err(Error::GetFileF)?;
Turns out this is already possible, but noisy, so the rip!
macro makes a bit more explicit:
let path = find_config_file().ok_or(Error::FindPathF)?; let path = rip! { find_config_file() => Error::FindPathF };
See also
- Error Handling in Rust §The real
try!
macro /?
operator - guard, a crate implementing "guard" expressions
Modules
prelude | Crate prelude when implementing traits |
Macros
fear | (Legacy) Alias for |
rip | try!-like error-handling macro |
tear | Turns a ValRet into a value or an early return |
tear_if | Explicit |
terror | (Legacy) Alias for |
Enums
Moral | A notion of good and bad for the rip! macro |
ValRet | Represents a usable value or an early return. Use with tear! |
Traits
Judge | Convert from and to Moral. Used in the rip! macro. |
Return | The ability to coerce to a ValRet and be used with the tear! macro |