The general idea is that inside a closure, return;
would return from the defining function instead of the closure.
fn main() {
// `return` would be a divergent expression and return from `main`
let id: i32 = "321".parse().or_else(|| return);
}
This would allow Rust to satisfy the Tennent’s Correspondence Principle.
In short, Tennent’s Correspondence Principle says:
For a given expression
expr
,|| expr
should be equivalent.
You could wrap arbitrary parts function body (even the whole function body) in a closure and execute it (|| { ... })()
and there should be no compile errors.
Let's look at a common pattern:
// Inside FromRequest::from_request method from Rocket
let connection = match get_connection() {
Ok(connection) => connection,
Err(error) => {
return Outcome::Failure((Status::InternalServerError, error.into());
}
}
get_connection()?
doesn't help me here as I need to decorate the error a touch before it gets returned, and then return it. I could use .map_err
:
// Inside FromRequest::from_request method from Rocket
let connection = match get_connection().map_err(|err| Outcome::Failure((Status::InternalServerError, error.into()))) {
Ok(connection) => connection,
Err(error) => { return error }
}
However I still need to actually return it. I still can't use ?
because this method doesn't return a Result (or something that implements Carrier).
Consider the following:
// Inside FromRequest::from_request method from Rocket
let connection = get_connection().or_else(|err| return Outcome::Failure((Status::InternalServerError, err)));
Once Carrier stabilizes the second option could work nice enough for this use case. The key point here is flexibility though.
Thoughts?