From conversions drive ? in Rust
Implement From for each underlying error and ? converts on its own.
use std::fmt;
use std::num::ParseIntError;
#[derive(Debug)]
enum LoadError {
BadNumber(ParseIntError),
Empty,
}
impl From<ParseIntError> for LoadError {
fn from(e: ParseIntError) -> Self {
LoadError::BadNumber(e)
}
}
impl fmt::Display for LoadError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
LoadError::BadNumber(e) => write!(f, "not a number: {e}"),
LoadError::Empty => write!(f, "nothing to load"),
}
}
}
fn total(raw: &str) -> Result<i32, LoadError> {
if raw.trim().is_empty() {
return Err(LoadError::Empty);
}
let mut sum = 0;
for part in raw.split(',') {
sum += part.trim().parse::<i32>()?;
}
Ok(sum)
}
fn main() {
println!("{:?}", total("1, 2, 3"));
println!("{}", total("1, x").unwrap_err());
println!("{}", total(" ").unwrap_err());
}
How it works
?callsFrom::fromon the error it is returning.- One
Fromimpl per foreign error type is all it takes. - The function then mixes error sources freely.
Keywords and builtins used here
ErrFromLoadErrorOkParseIntErrorResultSelfenumfmtfnforfromi32ifimplinletmainmatchmutreturnselfstrtotaluse
The run, in numbers
- Lines
- 40
- Characters to type
- 775
- Tokens
- 247
- Three-star pace
- 105 tpm
At the three-star pace of 105 tokens a minute, this run takes about 141 seconds.
Step 3 of 5 in Your own error types, step 10 of 15 in Error handling.