55use std:: convert:: { TryInto , TryFrom } ;
66
77#[ derive( Debug ) ]
8- struct Person {
9- name : String ,
10- age : usize ,
8+ struct Color {
9+ red : u8 ,
10+ green : u8 ,
11+ blue : u8 ,
1112}
1213
1314// I AM NOT DONE
15+
1416// 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.
2020//
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 {
3027 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 > {
3243 }
3344}
3445
3546fn main ( ) {
3647 // 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) ;
4262}
4363
4464#[ cfg( test) ]
4565mod tests {
4666 use super :: * ;
67+
4768 #[ 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 ( ) ;
6172 }
6273 #[ test]
6374 #[ 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 ( ) ;
6677 }
6778 #[ 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 ) ;
7184 }
7285
7386 #[ test]
7487 #[ 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 ( ) ;
7790 }
78-
7991 #[ test]
8092 #[ 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 ) ;
83102 }
84103
85104 #[ test]
86105 #[ 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 ( ) ;
89109 }
90-
91110 #[ test]
92111 #[ 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 ) ;
95123 }
96-
97124 #[ test]
98125 #[ 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 ( ) ;
101129 }
102- }
130+ }
0 commit comments