?
Chaining results using match can get pretty untidy; luckily, the ? operator
can be used to make things pretty again. ? is used at the end of an expression
returning a Result, and is equivalent to a match expression, where the
Err(err) branch expands to an early return Err(err), and the Ok(ok)
branch expands to an ok expression.
mod checked {
use core::num::traits::Sqrt;
#[derive(Drop)]
pub enum MathError {
DivisionByZero,
NegativeSquareRoot,
}
pub type MathResult = Result<u32, MathError>;
pub fn div(x: u32, y: u32) -> MathResult {
if y == 0 {
Err(MathError::DivisionByZero)
} else {
Ok(x / y)
}
}
pub fn sqrt(x: u32) -> MathResult {
match x {
0 => Ok(0),
_ => Ok(x.sqrt().into()),
}
}
// Intermediate function
pub fn op_(x: u32, y: u32) -> MathResult {
// if `div` "fails", then `DivisionByZero` will be `return`ed
let ratio = div(x, y)?;
// if `sqrt` "fails", then `NegativeSquareRoot` will be `return`ed
sqrt(ratio)
}
pub fn op(x: u32, y: u32) {
match op_(x, y) {
Err(why) => panic!(
"{:?}",
match why {
MathError::DivisionByZero => println!("division by zero"),
MathError::NegativeSquareRoot => println!("square root of negative number"),
},
),
Ok(value) => println!("{}", value),
}
}
}
fn main() {
checked::op(1, 10);
}
Be sure to check the documentation,
as there are many methods to map/compose Result.