How to do it...

  1. Create a Rust project to work on during this chapter with cargo new chapter-six.
  2. Navigate to the newly created chapter-six folder. For the rest of this chapter, we will assume that your command line is currently in this directory.
  3. Inside the folder src, create a new folder called bin.
  4. Delete the generated lib.rs file, as we are not creating a library.
  5. In the folder src/bin, create a file called custom_error.rs.
  6. Add the following code and run it with cargo run --bin custom_error:
1   use std::{error, fmt, io, num, result};
2 use std::fs::File;
3 use std::io::{BufReader, Read};
4
5 #[derive(Debug)]
6 // This is going to be our custom Error type
7 enum AgeReaderError {
8 Io(io::Error),
9 Parse(num::ParseIntError),
10 NegativeAge(),
11 }
12
13 // It is common to alias Result in an Error module
14 type Result<T> = result::Result<T, AgeReaderError>;
15
16 impl error::Error for AgeReaderError {
17 fn description(&self) -> &str {
18 // Defer to the existing description if possible
19 match *self {
20 AgeReaderError::Io(ref err) => err.description(),
21 AgeReaderError::Parse(ref err) => err.description(),
22 // Descriptions should be as short as possible
23 AgeReaderError::NegativeAge() => "Age is negative",
24 }
25 }
26
27 fn cause(&self) -> Option<&error::Error> {
28 // Return the underlying error, if any
29 match *self {
30 AgeReaderError::Io(ref err) => Some(err),
31 AgeReaderError::Parse(ref err) => Some(err),
32 AgeReaderError::NegativeAge() => None,
33 }
34 }
35 }
36
37 impl fmt::Display for AgeReaderError {
38 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
39 // Write a detailed description of the problem
40 match *self {
41 AgeReaderError::Io(ref err) => write!(f, "IO error: {}",
err),
42 AgeReaderError::Parse(ref err) => write!(f, "Parse
error: {}", err),
43 AgeReaderError::NegativeAge() => write!(f, "Logic error:
Age cannot be negative"),
44 }
45 }
46 }
47
48 // Implement From<T> for every sub-error
49 impl From<io::Error> for AgeReaderError {
50 fn from(err: io::Error) -> AgeReaderError {
51 AgeReaderError::Io(err)
52 }
53 }
54
55 impl From<num::ParseIntError> for AgeReaderError {
56 fn from(err: num::ParseIntError) -> AgeReaderError {
57 AgeReaderError::Parse(err)
58 }
59 }
60
61 fn main() {
62 // Assuming a file called age.txt exists
63 const FILENAME: &str = "age.txt";
64 let result = read_age(FILENAME);
65 match result {
66 Ok(num) => println!("{} contains the age {}", FILENAME,
num),
67 Err(AgeReaderError::Io(err)) => eprintln!("Failed to open
the file {}: {}", FILENAME, err),
68 Err(AgeReaderError::Parse(err)) => eprintln!(
69 "Failed to read the contents of {} as a number: {}",
70 FILENAME, err
71 ),
72 Err(AgeReaderError::NegativeAge()) => eprintln!("The age in
the file is negative"),
73 }
74 }
75
76 // Read an age out of a file
77 fn read_age(filename: &str) -> Result<i32> {
78 let file = File::open(filename)?;
79 let mut buf_reader = BufReader::new(file);
80 let mut content = String::new();
81 buf_reader.read_to_string(&mut content)?;
82 let age: i32 = content.trim().parse()?;
83 if age.is_positive() {
84 Ok(age)
85 } else {
86 Err(AgeReaderError::NegativeAge())
87 }
88 }
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.22.74.232