Error conversion
- Rust course
- Intermediate
- Lesson 68/115
- 4 min
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}"),
}Practice 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.
Starter code
use std::num::ParseIntError;
fn main() {
// buraya yaz
}Sample 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"));
}Expected output
Ok(42)
Err(Bos)
Err(Sayi(ParseIntError { kind: InvalidDigit }))
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 Implementing <code>From<A> for B</code> also gives which for free?
- Into<B> for A Correct answer
- From<B> for A
- Display for B
- Clone for A
Explanation: The standard library has a blanket impl: Into is provided automatically for every pair implementing From. That's why writing From is preferred.
2 Conversion trait
impl ____<ParseIntError> for UygHata {
fn from(e: ParseIntError) -> Self {
UygHata::Sayi(e)
}
}
impl From<ParseIntError> for UygHata {
fn from(e: ParseIntError) -> Self {
UygHata::Sayi(e)
}
}
Explanation: The ? operator uses From for conversion.
3 Call and result
| Term | Meaning |
|---|---|
ikile("21") |
Ok(42) |
ikile("") |
Err(Bos) |
ikile("x") |
Err(Sayi(..)) |
ikile("-3") |
Ok(-6) |