Rust
Error conversion
Convert between error types with the From trait.
Error conversion
Before returning an error, ? calls From::from. If you implement From for your own error type, lower-level errors convert automatically:
use std::num::ParseIntError;
#[derive(Debug)]
enum UygHata {
Sayi(ParseIntError),
Bos,
}
impl From<ParseIntError> for UygHata {
fn from(e: ParseIntError) -> Self {
UygHata::Sayi(e)
}
}
Now in a function returning Result<_, UygHata>, s.parse::<i32>()? works directly.
Using it
Thanks to the conversion, the function body stays simple, and the caller can act by error kind:
fn ikile(s: &str) -> Result<i32, UygHata> {
if s.is_empty() {
return Err(UygHata::Bos);
}
Ok(s.parse::<i32>()? * 2) // ParseIntError → UygHata::Sayi
}
match ikile("") {
Err(UygHata::Bos) => println!("girdi boş"),
Err(UygHata::Sayi(e)) => println!("sayı değil: {e}"),
Ok(n) => println!("{n}"),
}
Exercise Automatic conversion
Write UygHata, the From implementation and the ikile function above. Print the results of ikile("21"), ikile("") and ikile("x") with {:?} on separate lines.
Show example solution
use std::num::ParseIntError;
#[derive(Debug)]
enum UygHata {
Sayi(ParseIntError),
Bos,
}
impl From<ParseIntError> for UygHata {
fn from(e: ParseIntError) -> Self {
UygHata::Sayi(e)
}
}
fn ikile(s: &str) -> Result<i32, UygHata> {
if s.is_empty() {
return Err(UygHata::Bos);
}
Ok(s.parse::<i32>()? * 2)
}
fn main() {
println!("{:?}", ikile("21"));
println!("{:?}", ikile(""));
println!("{:?}", ikile("x"));
}
Test yourself
-
Implementing <code>From<A> for B</code> also gives which for free?
- Into<B> for A
- From<B> for A
- Display for B
- Clone for A
Show answer
Into<B> for A — The standard library has a blanket impl: Into is provided automatically for every pair implementing From. That's why writing From is preferred.
-
Conversion trait
impl ____<ParseIntError> for UygHata {
fn from(e: ParseIntError) -> Self {
UygHata::Sayi(e)
}
}
Show answer
impl From<ParseIntError> for UygHata {
fn from(e: ParseIntError) -> Self {
UygHata::Sayi(e)
}
}
-
Call and result
- ikile("21")
- Ok(42)
- ikile("")
- Err(Bos)
- ikile("x")
- Err(Sayi(..))
- ikile("-3")
- Ok(-6)
Next lesson: Adding context