1
+ // try_from_into.rs
1
2
// TryFrom is a simple and safe type conversion that may fail in a controlled way under some circumstances.
2
3
// Basically, this is the same as From. The main difference is that this should return a Result type
3
4
// instead of the target type itself.
4
5
// You can read more about it at https://doc.rust-lang.org/std/convert/trait.TryFrom.html
5
6
use std:: convert:: { TryFrom , TryInto } ;
6
- use std:: error;
7
7
8
8
#[ derive( Debug , PartialEq ) ]
9
9
struct Color {
@@ -12,49 +12,61 @@ struct Color {
12
12
blue : u8 ,
13
13
}
14
14
15
+ // We will use this error type for these `TryFrom` conversions.
16
+ #[ derive( Debug , PartialEq ) ]
17
+ enum IntoColorError {
18
+ // Incorrect length of slice
19
+ BadLen ,
20
+ // Integer conversion error
21
+ IntConversion ,
22
+ }
23
+
15
24
// I AM NOT DONE
16
25
17
26
// Your task is to complete this implementation
18
27
// and return an Ok result of inner type Color.
19
28
// You need to create an implementation for a tuple of three integers,
20
- // an array of three integers and a slice of integers.
29
+ // an array of three integers, and a slice of integers.
21
30
//
22
31
// Note that the implementation for tuple and array will be checked at compile time,
23
32
// but the slice implementation needs to check the slice length!
24
33
// Also note that correct RGB color values must be integers in the 0..=255 range.
25
34
26
35
// Tuple implementation
27
36
impl TryFrom < ( i16 , i16 , i16 ) > for Color {
28
- type Error = Box < dyn error:: Error > ;
29
- fn try_from ( tuple : ( i16 , i16 , i16 ) ) -> Result < Self , Self :: Error > { }
37
+ type Error = IntoColorError ;
38
+ fn try_from ( tuple : ( i16 , i16 , i16 ) ) -> Result < Self , Self :: Error > {
39
+ }
30
40
}
31
41
32
42
// Array implementation
33
43
impl TryFrom < [ i16 ; 3 ] > for Color {
34
- type Error = Box < dyn error:: Error > ;
35
- fn try_from ( arr : [ i16 ; 3 ] ) -> Result < Self , Self :: Error > { }
44
+ type Error = IntoColorError ;
45
+ fn try_from ( arr : [ i16 ; 3 ] ) -> Result < Self , Self :: Error > {
46
+ }
36
47
}
37
48
38
49
// Slice implementation
39
50
impl TryFrom < & [ i16 ] > for Color {
40
- type Error = Box < dyn error:: Error > ;
41
- fn try_from ( slice : & [ i16 ] ) -> Result < Self , Self :: Error > { }
51
+ type Error = IntoColorError ;
52
+ fn try_from ( slice : & [ i16 ] ) -> Result < Self , Self :: Error > {
53
+ }
42
54
}
43
55
44
56
fn main ( ) {
45
57
// Use the `from` function
46
58
let c1 = Color :: try_from ( ( 183 , 65 , 14 ) ) ;
47
59
println ! ( "{:?}" , c1) ;
48
60
49
- // Since From is implemented for Color, we should be able to use Into
61
+ // Since TryFrom is implemented for Color, we should be able to use TryInto
50
62
let c2: Result < Color , _ > = [ 183 , 65 , 14 ] . try_into ( ) ;
51
63
println ! ( "{:?}" , c2) ;
52
64
53
65
let v = vec ! [ 183 , 65 , 14 ] ;
54
- // With slice we should use `from ` function
66
+ // With slice we should use `try_from ` function
55
67
let c3 = Color :: try_from ( & v[ ..] ) ;
56
68
println ! ( "{:?}" , c3) ;
57
- // or take slice within round brackets and use Into
69
+ // or take slice within round brackets and use TryInto
58
70
let c4: Result < Color , _ > = ( & v[ ..] ) . try_into ( ) ;
59
71
println ! ( "{:?}" , c4) ;
60
72
}
@@ -65,15 +77,24 @@ mod tests {
65
77
66
78
#[ test]
67
79
fn test_tuple_out_of_range_positive ( ) {
68
- assert ! ( Color :: try_from( ( 256 , 1000 , 10000 ) ) . is_err( ) ) ;
80
+ assert_eq ! (
81
+ Color :: try_from( ( 256 , 1000 , 10000 ) ) ,
82
+ Err ( IntoColorError :: IntConversion )
83
+ ) ;
69
84
}
70
85
#[ test]
71
86
fn test_tuple_out_of_range_negative ( ) {
72
- assert ! ( Color :: try_from( ( -1 , -10 , -256 ) ) . is_err( ) ) ;
87
+ assert_eq ! (
88
+ Color :: try_from( ( -1 , -10 , -256 ) ) ,
89
+ Err ( IntoColorError :: IntConversion )
90
+ ) ;
73
91
}
74
92
#[ test]
75
93
fn test_tuple_sum ( ) {
76
- assert ! ( Color :: try_from( ( -1 , 255 , 255 ) ) . is_err( ) ) ;
94
+ assert_eq ! (
95
+ Color :: try_from( ( -1 , 255 , 255 ) ) ,
96
+ Err ( IntoColorError :: IntConversion )
97
+ ) ;
77
98
}
78
99
#[ test]
79
100
fn test_tuple_correct ( ) {
@@ -91,17 +112,17 @@ mod tests {
91
112
#[ test]
92
113
fn test_array_out_of_range_positive ( ) {
93
114
let c: Result < Color , _ > = [ 1000 , 10000 , 256 ] . try_into ( ) ;
94
- assert ! ( c. is_err ( ) ) ;
115
+ assert_eq ! ( c, Err ( IntoColorError :: IntConversion ) ) ;
95
116
}
96
117
#[ test]
97
118
fn test_array_out_of_range_negative ( ) {
98
119
let c: Result < Color , _ > = [ -10 , -256 , -1 ] . try_into ( ) ;
99
- assert ! ( c. is_err ( ) ) ;
120
+ assert_eq ! ( c, Err ( IntoColorError :: IntConversion ) ) ;
100
121
}
101
122
#[ test]
102
123
fn test_array_sum ( ) {
103
124
let c: Result < Color , _ > = [ -1 , 255 , 255 ] . try_into ( ) ;
104
- assert ! ( c. is_err ( ) ) ;
125
+ assert_eq ! ( c, Err ( IntoColorError :: IntConversion ) ) ;
105
126
}
106
127
#[ test]
107
128
fn test_array_correct ( ) {
@@ -119,17 +140,26 @@ mod tests {
119
140
#[ test]
120
141
fn test_slice_out_of_range_positive ( ) {
121
142
let arr = [ 10000 , 256 , 1000 ] ;
122
- assert ! ( Color :: try_from( & arr[ ..] ) . is_err( ) ) ;
143
+ assert_eq ! (
144
+ Color :: try_from( & arr[ ..] ) ,
145
+ Err ( IntoColorError :: IntConversion )
146
+ ) ;
123
147
}
124
148
#[ test]
125
149
fn test_slice_out_of_range_negative ( ) {
126
150
let arr = [ -256 , -1 , -10 ] ;
127
- assert ! ( Color :: try_from( & arr[ ..] ) . is_err( ) ) ;
151
+ assert_eq ! (
152
+ Color :: try_from( & arr[ ..] ) ,
153
+ Err ( IntoColorError :: IntConversion )
154
+ ) ;
128
155
}
129
156
#[ test]
130
157
fn test_slice_sum ( ) {
131
158
let arr = [ -1 , 255 , 255 ] ;
132
- assert ! ( Color :: try_from( & arr[ ..] ) . is_err( ) ) ;
159
+ assert_eq ! (
160
+ Color :: try_from( & arr[ ..] ) ,
161
+ Err ( IntoColorError :: IntConversion )
162
+ ) ;
133
163
}
134
164
#[ test]
135
165
fn test_slice_correct ( ) {
@@ -148,11 +178,11 @@ mod tests {
148
178
#[ test]
149
179
fn test_slice_excess_length ( ) {
150
180
let v = vec ! [ 0 , 0 , 0 , 0 ] ;
151
- assert ! ( Color :: try_from( & v[ ..] ) . is_err ( ) ) ;
181
+ assert_eq ! ( Color :: try_from( & v[ ..] ) , Err ( IntoColorError :: BadLen ) ) ;
152
182
}
153
183
#[ test]
154
184
fn test_slice_insufficient_length ( ) {
155
185
let v = vec ! [ 0 , 0 ] ;
156
- assert ! ( Color :: try_from( & v[ ..] ) . is_err ( ) ) ;
186
+ assert_eq ! ( Color :: try_from( & v[ ..] ) , Err ( IntoColorError :: BadLen ) ) ;
157
187
}
158
188
}
0 commit comments