I am solving rustlings exercises and have issue with errors2, below is my code:
pub fn total_cost(item_quantity: &str) -> Result<i32, ParseIntError> {
let processing_fee = 1;
let cost_per_item = 5;
let qty = item_quantity.parse::<i32>();
let quantity_result = match qty {
Ok(qty) => (qty * cost_per_item + processing_fee),
Err(err) => panic!("invalid digit found in string {:?}", err),
};
Ok(quantity_result)
}
Ok part works but I have no idea how to implement properly Err part. Here is a test for the code:
#[test]
fn item_quantity_is_an_invalid_number() {
assert_eq!(
total_cost("beep boop").unwrap_err().to_string(),
"invalid digit found in string"
);
}
Currently I have following message:
panicked at ‘invalid digit found in string ParseIntError { kind:
InvalidDigit }’
>Solution :
The test is doing an unwrap_err(), meaning the test wants to see an Err returned from your function. You already have a ParseIntError, so return it instead of panicking; change this line
Err(err) => panic!("invalid digit found in string {:?}", err),
to
Err(err) => return Err(err),
That should let the test pass.
A further refinement of the code is to use the ? operator, which is specifically for returning errors when they occur. Then you would replace the entire match with:
let quantity_result = qty? * cost_per_item + processing_fee;
or, more idiomatically, put the ? on the line where the error occurred:
let qty = item_quantity.parse::<i32>()?;
so that qty itself is an i32 and not a Result<i32, ParseIntError>.