1- // errors6 .rs
1+ // errors5 .rs
22//
3- // Using catch-all error types like `Box<dyn error::Error>` isn't recommended
4- // for library code, where callers might want to make decisions based on the
5- // error content, instead of printing it out or propagating it further. Here, we
6- // define a custom error type to make it possible for callers to decide what to
7- // do next when our function returns an error.
3+ // This program uses an altered version of the code from errors4.
84//
9- // Execute `rustlings hint errors6` or use the `hint` watch subcommand for a
5+ // This exercise uses some concepts that we won't get to until later in the
6+ // course, like `Box` and the `From` trait. It's not important to understand
7+ // them in detail right now, but you can read ahead if you like. For now, think
8+ // of the `Box<dyn ???>` type as an "I want anything that does ???" type, which,
9+ // given Rust's usual standards for runtime safety, should strike you as
10+ // somewhat lenient!
11+ //
12+ // In short, this particular use case for boxes is for when you want to own a
13+ // value and you care only that it is a type which implements a particular
14+ // trait. To do so, The Box is declared as of type Box<dyn Trait> where Trait is
15+ // the trait the compiler looks for on any value used in that context. For this
16+ // exercise, that context is the potential errors which can be returned in a
17+ // Result.
18+ //
19+ // What can we use to describe both errors? In other words, is there a trait
20+ // which both errors implement?
21+ //
22+ // Execute `rustlings hint errors5` or use the `hint` watch subcommand for a
1023// hint.
1124
12- // I AM NOT DONE
13-
25+ use std:: error;
26+ use std:: error:: Error ;
27+ use std:: fmt;
1428use std:: num:: ParseIntError ;
1529
16- // This is a custom error type that we will be using in `parse_pos_nonzero()`.
17- #[ derive( PartialEq , Debug ) ]
18- enum ParsePosNonzeroError {
19- Creation ( CreationError ) ,
20- ParseInt ( ParseIntError ) ,
21- }
22-
23- impl ParsePosNonzeroError {
24- fn from_creation ( err : CreationError ) -> ParsePosNonzeroError {
25- ParsePosNonzeroError :: Creation ( err)
26- }
27- // TODO: add another error conversion function here.
28- // fn from_parseint...
29- }
30-
31- fn parse_pos_nonzero ( s : & str ) -> Result < PositiveNonzeroInteger , ParsePosNonzeroError > {
32- // TODO: change this to return an appropriate error instead of panicking
33- // when `parse()` returns an error.
34- let x: i64 = s. parse ( ) . unwrap ( ) ;
35- PositiveNonzeroInteger :: new ( x) . map_err ( ParsePosNonzeroError :: from_creation)
30+ // TODO: update the return type of `main()` to make this compile.
31+ fn main ( ) -> Result < ( ) , Box < dyn Error > > {
32+ let pretend_user_input = "42" ;
33+ let x: i64 = pretend_user_input. parse ( ) ?;
34+ println ! ( "output={:?}" , PositiveNonzeroInteger :: new( x) ?) ;
35+ Ok ( ( ) )
3636}
3737
3838// Don't change anything below this line.
@@ -56,39 +56,15 @@ impl PositiveNonzeroInteger {
5656 }
5757}
5858
59- #[ cfg( test) ]
60- mod test {
61- use super :: * ;
62-
63- #[ test]
64- fn test_parse_error ( ) {
65- // We can't construct a ParseIntError, so we have to pattern match.
66- assert ! ( matches!(
67- parse_pos_nonzero( "not a number" ) ,
68- Err ( ParsePosNonzeroError :: ParseInt ( _) )
69- ) ) ;
70- }
71-
72- #[ test]
73- fn test_negative ( ) {
74- assert_eq ! (
75- parse_pos_nonzero( "-555" ) ,
76- Err ( ParsePosNonzeroError :: Creation ( CreationError :: Negative ) )
77- ) ;
78- }
79-
80- #[ test]
81- fn test_zero ( ) {
82- assert_eq ! (
83- parse_pos_nonzero( "0" ) ,
84- Err ( ParsePosNonzeroError :: Creation ( CreationError :: Zero ) )
85- ) ;
86- }
87-
88- #[ test]
89- fn test_positive ( ) {
90- let x = PositiveNonzeroInteger :: new ( 42 ) ;
91- assert ! ( x. is_ok( ) ) ;
92- assert_eq ! ( parse_pos_nonzero( "42" ) , Ok ( x. unwrap( ) ) ) ;
59+ // This is required so that `CreationError` can implement `error::Error`.
60+ impl fmt:: Display for CreationError {
61+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
62+ let description = match * self {
63+ CreationError :: Negative => "number is negative" ,
64+ CreationError :: Zero => "number is zero" ,
65+ } ;
66+ f. write_str ( description)
9367 }
9468}
69+
70+ impl error:: Error for CreationError { }
0 commit comments