errors5.rs (2011B)
1 // This exercise is an altered version of the `errors4` exercise. It uses some 2 // concepts that we won't get to until later in the course, like `Box` and the 3 // `From` trait. It's not important to understand them in detail right now, but 4 // you can read ahead if you like. For now, think of the `Box<dyn ???>` type as 5 // an "I want anything that does ???" type. 6 // 7 // In short, this particular use case for boxes is for when you want to own a 8 // value and you care only that it is a type which implements a particular 9 // trait. To do so, the `Box` is declared as of type `Box<dyn Trait>` where 10 // `Trait` is the trait the compiler looks for on any value used in that 11 // context. For this exercise, that context is the potential errors which 12 // can be returned in a `Result`. 13 14 use std::error::Error; 15 use std::fmt; 16 17 #[derive(PartialEq, Debug)] 18 enum CreationError { 19 Negative, 20 Zero, 21 } 22 23 // This is required so that `CreationError` can implement `Error`. 24 impl fmt::Display for CreationError { 25 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 26 let description = match *self { 27 CreationError::Negative => "number is negative", 28 CreationError::Zero => "number is zero", 29 }; 30 f.write_str(description) 31 } 32 } 33 34 impl Error for CreationError {} 35 36 #[derive(PartialEq, Debug)] 37 struct PositiveNonzeroInteger(u64); 38 39 impl PositiveNonzeroInteger { 40 fn new(value: i64) -> Result<PositiveNonzeroInteger, CreationError> { 41 match value { 42 x if x < 0 => Err(CreationError::Negative), 43 0 => Err(CreationError::Zero), 44 x => Ok(PositiveNonzeroInteger(x as u64)), 45 } 46 } 47 } 48 49 // TODO: Add the correct return type `Result<(), Box<dyn ???>>`. What can we 50 // use to describe both errors? Is there a trait which both errors implement? 51 fn main() -> Result<(), Box<dyn Error>> { 52 let pretend_user_input = "42"; 53 let x: i64 = pretend_user_input.parse()?; 54 println!("output={:?}", PositiveNonzeroInteger::new(x)?); 55 Ok(()) 56 }