5
5
use std:: convert:: { TryInto , TryFrom } ;
6
6
7
7
#[ derive( Debug ) ]
8
- struct Person {
9
- name : String ,
10
- age : usize ,
8
+ struct Color {
9
+ red : u8 ,
10
+ green : u8 ,
11
+ blue : u8 ,
11
12
}
12
13
13
14
// I AM NOT DONE
15
+
14
16
// Your task is to complete this implementation
15
- // in order for the line `let p = Person::try_from("Mark,20")` to compile
16
- // and return an Ok result of inner type Person.
17
- // Please note that you'll need to parse the age component into a `usize`
18
- // with something like `"4".parse::<usize>()`. The outcome of this needs to
19
- // be handled appropriately.
17
+ // and return an Ok result of inner type Color.
18
+ // You need create implementation for a tuple of three integer,
19
+ // an array of three integer and slice of integer.
20
20
//
21
- // Steps:
22
- // 1. If the length of the provided string is 0, then return an error
23
- // 2. Split the given string on the commas present in it
24
- // 3. Extract the first element from the split operation and use it as the name
25
- // 4. If the name is empty, then return an error.
26
- // 5. Extract the other element from the split operation and parse it into a `usize` as the age
27
- // If while parsing the age, something goes wrong, then return an error
28
- // Otherwise, then return a Result of a Person object
29
- impl TryFrom < & str > for Person {
21
+ // Note, that implementation for tuple and array will be checked at compile-time,
22
+ // but slice implementation need check slice length!
23
+ // Also note, that chunk of correct rgb color must be integer in range 0..=255.
24
+
25
+ // Tuple implementation
26
+ impl TryFrom < ( i16 , i16 , i16 ) > for Color {
30
27
type Error = String ;
31
- fn try_from ( s : & str ) -> Result < Self , Self :: Error > {
28
+ fn try_from ( tuple : ( i16 , i16 , i16 ) ) -> Result < Self , Self :: Error > {
29
+ }
30
+ }
31
+
32
+ // Array implementation
33
+ impl TryFrom < [ i16 ; 3 ] > for Color {
34
+ type Error = String ;
35
+ fn try_from ( arr : [ i16 ; 3 ] ) -> Result < Self , Self :: Error > {
36
+ }
37
+ }
38
+
39
+ // Slice implementation
40
+ impl TryFrom < & [ i16 ] > for Color {
41
+ type Error = String ;
42
+ fn try_from ( slice : & [ i16 ] ) -> Result < Self , Self :: Error > {
32
43
}
33
44
}
34
45
35
46
fn main ( ) {
36
47
// Use the `from` function
37
- let p1 = Person :: try_from ( "Mark,20" ) ;
38
- // Since From is implemented for Person, we should be able to use Into
39
- let p2: Result < Person , _ > = "Gerald,70" . try_into ( ) ;
40
- println ! ( "{:?}" , p1) ;
41
- println ! ( "{:?}" , p2) ;
48
+ let c1 = Color :: try_from ( ( 183 , 65 , 14 ) ) ;
49
+ println ! ( "{:?}" , c1) ;
50
+
51
+ // Since From is implemented for Color, we should be able to use Into
52
+ let c2: Result < Color , _ > = [ 183 , 65 , 14 ] . try_into ( ) ;
53
+ println ! ( "{:?}" , c2) ;
54
+
55
+ let v = vec ! [ 183 , 65 , 14 ] ;
56
+ // With slice we should use `from` function
57
+ let c3 = Color :: try_from ( & v[ ..] ) ;
58
+ println ! ( "{:?}" , c3) ;
59
+ // or take slice within round brackets and use Into
60
+ let c4: Result < Color , _ > = ( & v[ ..] ) . try_into ( ) ;
61
+ println ! ( "{:?}" , c4) ;
42
62
}
43
63
44
64
#[ cfg( test) ]
45
65
mod tests {
46
66
use super :: * ;
67
+
47
68
#[ test]
48
- fn test_bad_convert ( ) {
49
- // Test that error is returned when bad string is provided
50
- let p = Person :: try_from ( "" ) ;
51
- assert ! ( p. is_err( ) ) ;
52
- }
53
- #[ test]
54
- fn test_good_convert ( ) {
55
- // Test that "Mark,20" works
56
- let p = Person :: try_from ( "Mark,20" ) ;
57
- assert ! ( p. is_ok( ) ) ;
58
- let p = p. unwrap ( ) ;
59
- assert_eq ! ( p. name, "Mark" ) ;
60
- assert_eq ! ( p. age, 20 ) ;
69
+ #[ should_panic]
70
+ fn test_tuple_out_of_range_positive ( ) {
71
+ let _ = Color :: try_from ( ( 256 , 1000 , 10000 ) ) . unwrap ( ) ;
61
72
}
62
73
#[ test]
63
74
#[ should_panic]
64
- fn test_panic_empty_input ( ) {
65
- let p : Person = "" . try_into ( ) . unwrap ( ) ;
75
+ fn test_tuple_out_of_range_negative ( ) {
76
+ let _ = Color :: try_from ( ( - 1 , - 10 , - 256 ) ) . unwrap ( ) ;
66
77
}
67
78
#[ test]
68
- #[ should_panic]
69
- fn test_panic_bad_age ( ) {
70
- let p = Person :: try_from ( "Mark,twenty" ) . unwrap ( ) ;
79
+ fn test_tuple_correct ( ) {
80
+ let c: Color = ( 183 , 65 , 14 ) . try_into ( ) . unwrap ( ) ;
81
+ assert_eq ! ( c. red, 183 ) ;
82
+ assert_eq ! ( c. green, 65 ) ;
83
+ assert_eq ! ( c. blue, 14 ) ;
71
84
}
72
85
73
86
#[ test]
74
87
#[ should_panic]
75
- fn test_missing_comma_and_age ( ) {
76
- let _: Person = "Mark" . try_into ( ) . unwrap ( ) ;
88
+ fn test_array_out_of_range_positive ( ) {
89
+ let _: Color = [ 1000 , 10000 , 256 ] . try_into ( ) . unwrap ( ) ;
77
90
}
78
-
79
91
#[ test]
80
92
#[ should_panic]
81
- fn test_missing_age ( ) {
82
- let _: Person = "Mark," . try_into ( ) . unwrap ( ) ;
93
+ fn test_array_out_of_range_negative ( ) {
94
+ let _: Color = [ -10 , -256 , -1 ] . try_into ( ) . unwrap ( ) ;
95
+ }
96
+ #[ test]
97
+ fn test_array_correct ( ) {
98
+ let c: Color = [ 183 , 65 , 14 ] . try_into ( ) . unwrap ( ) ;
99
+ assert_eq ! ( c. red, 183 ) ;
100
+ assert_eq ! ( c. green, 65 ) ;
101
+ assert_eq ! ( c. blue, 14 ) ;
83
102
}
84
103
85
104
#[ test]
86
105
#[ should_panic]
87
- fn test_missing_name ( ) {
88
- let _ : Person = ",1" . try_into ( ) . unwrap ( ) ;
106
+ fn test_slice_out_of_range_positive ( ) {
107
+ let arr = [ 10000 , 256 , 1000 ] ;
108
+ let _ = Color :: try_from ( & arr[ ..] ) . unwrap ( ) ;
89
109
}
90
-
91
110
#[ test]
92
111
#[ should_panic]
93
- fn test_missing_name_and_age ( ) {
94
- let _: Person = "," . try_into ( ) . unwrap ( ) ;
112
+ fn test_slice_out_of_range_negative ( ) {
113
+ let arr = [ -256 , -1 , -10 ] ;
114
+ let _ = Color :: try_from ( & arr[ ..] ) . unwrap ( ) ;
115
+ }
116
+ #[ test]
117
+ fn test_slice_correct ( ) {
118
+ let v = vec ! [ 183 , 65 , 14 ] ;
119
+ let c = Color :: try_from ( & v[ ..] ) . unwrap ( ) ;
120
+ assert_eq ! ( c. red, 183 ) ;
121
+ assert_eq ! ( c. green, 65 ) ;
122
+ assert_eq ! ( c. blue, 14 ) ;
95
123
}
96
-
97
124
#[ test]
98
125
#[ should_panic]
99
- fn test_missing_name_and_invalid_age ( ) {
100
- let _: Person = ",one" . try_into ( ) . unwrap ( ) ;
126
+ fn test_slice_excess_length ( ) {
127
+ let v = vec ! [ 0 , 0 , 0 , 0 ] ;
128
+ let _ = Color :: try_from ( & v[ ..] ) . unwrap ( ) ;
101
129
}
102
- }
130
+ }
0 commit comments