1- use :: std:: fs;
1+ use std:: fs;
22use std:: io:: { self , Read } ;
33use std:: num:: ParseIntError ;
44
55// FUNCTIONS defined outside main()
6- //
7- fn divide ( a : f64 , b : f64 ) -> Result < f64 , String > { // Returns result --> caller must handle Ok or Err
8- if b == 0.0 {
6+ //
7+ fn divide ( a : f64 , b : f64 ) -> Result < f64 , String > {
8+ // Returns result --> caller must handle Ok or Err
9+ if b == 0.0 {
910 Err ( String :: from ( "Can't divide by zero" ) )
10- } else {
11- Ok ( a/ b)
11+ } else {
12+ Ok ( a / b)
1213 }
1314}
1415
1516fn read_file ( path : & str ) -> Result < String , io:: Error > {
16- let contents = fs:: read_to_string ( path) ?; // returns Err if file missing
17+ let contents = fs:: read_to_string ( path) ?; // returns Err if file missing
1718 Ok ( contents)
1819}
1920
2021// Using ? with multiple operations
2122fn read_and_parse ( path : & str ) -> Result < i32 , Box < dyn std:: error:: Error > > {
22- let contents = fs:: read_to_string ( path) ?; // could fail -> file missing
23+ let contents = fs:: read_to_string ( path) ?; // could fail -> file missing
2324 let number: i32 = contents. trim ( ) . parse ( ) ?; // could fail -> not a number
2425 Ok ( number)
2526}
@@ -44,83 +45,81 @@ impl std::fmt::Display for AppError {
4445}
4546
4647fn safe_divide ( a : f64 , b : f64 ) -> Result < f64 , AppError > {
47- if b == 0.0 {
48+ if b == 0.0 {
4849 Err ( AppError :: DivisionByZero )
49- } else {
50- Ok ( a/ b)
50+ } else {
51+ Ok ( a / b)
5152 }
5253}
5354
54- fn main ( ) {
55- let result = "42" . parse :: < i32 > ( ) . unwrap ( ) ; // unwrap() => give me the value, crash if Err
55+ fn main ( ) {
56+ let result = "42" . parse :: < i32 > ( ) . unwrap ( ) ; // unwrap() => give me the value, crash if Err
5657 println ! ( "parsed: {}" , result) ;
57-
58+
5859 // PART - 2: match - full control over Ok and Err
59-
60- match divide ( 10.0 , 2.0 ) {
60+
61+ match divide ( 10.0 , 2.0 ) {
6162 Ok ( result) => println ! ( "10/2 = {}" , result) ,
6263 Err ( e) => println ! ( "Error: {}" , e) ,
6364 }
64-
65- match divide ( 10.0 , 0.0 ) {
65+
66+ match divide ( 10.0 , 0.0 ) {
6667 Ok ( result) => println ! ( "10/ 0 = {}" , result) ,
6768 Err ( e) => println ! ( "Error: {}" , e) ,
6869 }
69-
70-
71- match read_file ( "hello.txt" ) {
70+
71+ match read_file ( "hello.txt" ) {
7272 Ok ( contents) => println ! ( "File contents: {}" , contents) ,
7373 Err ( e) => println ! ( "Could not read file: {}" , e) ,
7474 }
75-
75+
7676 // PART 4: unwrap_or == safe default value
77-
78- // if Err, use the default value instead of crashing
79- let name = std:: env:: var ( "USERNAME" )
80- . unwrap_or ( String :: from ( "guest" ) ) ;
77+
78+ // if Err, use the default value instead of crashing
79+ let name = std:: env:: var ( "USERNAME" ) . unwrap_or ( String :: from ( "guest" ) ) ;
8180 println ! ( "Hello, {}!" , name) ;
82-
81+
8382 let number = "abc" . parse :: < i32 > ( ) . unwrap_or ( 0 ) ;
8483 println ! ( "parsed number (or 0): {}" , number) ;
85-
84+
8685 // PART 5: if let -- handle just the success case
87-
86+
8887 // if let Ok -- only runs if result is Ok
8988 if let Ok ( n) = "99" . parse :: < i32 > ( ) {
9089 println ! ( "Successfully parsed: {}" , n) ;
91- }
92-
90+ }
91+
9392 // uf let Some -- only runs if Option has a value
94- let numbers = vec ! [ 1 , 2 , 3 ] ;
93+ let numbers = vec ! [ 1 , 2 , 3 ] ;
9594 if let Some ( first) = numbers. first ( ) {
9695 println ! ( "First number: {}" , first) ;
9796 }
98-
97+
9998 // Part 6: Custom Error Types
100-
101- match safe_divide ( 10.0 , 2.0 ) {
99+
100+ match safe_divide ( 10.0 , 2.0 ) {
102101 Ok ( result) => println ! ( "Result: {}" , result) ,
103102 Err ( e) => println ! ( "AppError: {}" , e) ,
104103 }
105-
106- match safe_divide ( 10.0 , 0.0 ) {
104+
105+ match safe_divide ( 10.0 , 0.0 ) {
107106 Ok ( result) => println ! ( "Result: {}" , result) ,
108107 Err ( e) => println ! ( "AppError: {}" , e) ,
109108 }
110-
109+
111110 // PART 7: Three levels of Error Handling -- side by side
112-
111+
113112 // level 1 -- unwrap (crash on error)
114113 let a = "10" . parse :: < i32 > ( ) . unwrap ( ) ;
115-
114+
116115 // level 2 -- unwrap_or (default on error)
117116 let b = "bad" . parse :: < i32 > ( ) . unwrap_or ( 0 ) ;
118-
117+
119118 // level 3 -- match (full control)
120- let c= match "42" . parse :: < i32 > ( ) {
119+ let c = match "42" . parse :: < i32 > ( ) {
121120 Ok ( n) => n,
122121 Err ( _) => -1 ,
123122 } ;
124-
123+
125124 println ! ( "a = {}, b = {}, c = {}" , a, b, c)
126- }
125+ }
0 commit comments