Expand description
Traits and types to support ret!()/throw!() and backtrace in a #[cex] fn.
§The ret!()/throw!() macros
The underlying control flow constructs of these two macros are return.
However, ret!()/throw!() macros are preferred over return because:
-
Using
returnis subject to changes on feature oflog/env_log, while usingret!()/throw!()are not. -
ret!()/throw!()are cool and more clear thanreturn. -
ret!()supports Ok-wrapping.
§The syntax of ret!()
-
ret!( ok_value ), or -
ret!( result_value )
In other words, you can use ret!() to return an Ok expression:
#[cex] fn foo() -> Result!( i32 throws String ) {
ret!( 42 ); // Ok-wrapping
}or you can use ret!() to return a Result expression:
#[cex] fn foo() -> Result!( i32 throws String ) {
ret!( Ok( 42 ));
// or ret!( Err( String::from( "oops" )))
}§The syntax of throw!()
is throws!( err_value ).
You can use throw!() to return an Err expression:
#[cex] fn foo() -> Result!( i32 throws String, SomeError ) {
throw!( String::from( "oops" ))
// or throw!( SomeError )
}Thanks to the power of Exchange:
#[cex] fn bar() -> Result!( i32 throws String, &'static str, SomeError ) {
match foo() {
Ok(v) => ret!(v),
Err(e) => throw!(e), // all errors in foo()'s throws are in bar()'s
}
}Thanks to the power of ? which looks like throwing checked exceptions:
// equivalent to bar()
#[cex] fn baz() -> Result!( i32 throws String, &'static str, SomeError ) {
ret!( foo()? ) // of course you can use `?` to propagate errors
}