@ -1,9 +1,9 @@
// try_from_into.rs
// TryFrom is a simple and safe type conversion that may fail in a controlled way under some circumstances.
// Basically, this is the same as From. The main difference is that this should return a Result type
// instead of the target type itself.
// You can read more about it at https://doc.rust-lang.org/std/convert/trait.TryFrom.html
use std ::convert ::{ TryFrom , TryInto } ;
use std ::error ;
#[ derive(Debug, PartialEq) ]
struct Color {
@ -12,12 +12,21 @@ struct Color {
blue : u8 ,
}
// We will use this error type for these `TryFrom` conversions.
#[ derive(Debug, PartialEq) ]
enum IntoColorError {
// Incorrect length of slice
BadLen ,
// Integer conversion error
IntConversion ,
}
// I AM NOT DONE
// Your task is to complete this implementation
// and return an Ok result of inner type Color.
// You need to create an implementation for a tuple of three integers,
// an array of three integers and a slice of integers.
// an array of three integers , and a slice of integers.
//
// Note that the implementation for tuple and array will be checked at compile time,
// but the slice implementation needs to check the slice length!
@ -25,20 +34,23 @@ struct Color {
// Tuple implementation
impl TryFrom < ( i16 , i16 , i16 ) > for Color {
type Error = Box < dyn error ::Error > ;
fn try_from ( tuple : ( i16 , i16 , i16 ) ) -> Result < Self , Self ::Error > { }
type Error = IntoColorError ;
fn try_from ( tuple : ( i16 , i16 , i16 ) ) -> Result < Self , Self ::Error > {
}
}
// Array implementation
impl TryFrom < [ i16 ; 3 ] > for Color {
type Error = Box < dyn error ::Error > ;
fn try_from ( arr : [ i16 ; 3 ] ) -> Result < Self , Self ::Error > { }
type Error = IntoColorError ;
fn try_from ( arr : [ i16 ; 3 ] ) -> Result < Self , Self ::Error > {
}
}
// Slice implementation
impl TryFrom < & [ i16 ] > for Color {
type Error = Box < dyn error ::Error > ;
fn try_from ( slice : & [ i16 ] ) -> Result < Self , Self ::Error > { }
type Error = IntoColorError ;
fn try_from ( slice : & [ i16 ] ) -> Result < Self , Self ::Error > {
}
}
fn main ( ) {
@ -46,15 +58,15 @@ fn main() {
let c1 = Color ::try_from ( ( 183 , 65 , 14 ) ) ;
println! ( "{:?}" , c1 ) ;
// Since From is implemented for Color, we should be able to use Into
// Since Try From is implemented for Color, we should be able to use Try Into
let c2 : Result < Color , _ > = [ 183 , 65 , 14 ] . try_into ( ) ;
println! ( "{:?}" , c2 ) ;
let v = vec! [ 183 , 65 , 14 ] ;
// With slice we should use ` from` function
// With slice we should use ` try_ from` function
let c3 = Color ::try_from ( & v [ .. ] ) ;
println! ( "{:?}" , c3 ) ;
// or take slice within round brackets and use Into
// or take slice within round brackets and use Try Into
let c4 : Result < Color , _ > = ( & v [ .. ] ) . try_into ( ) ;
println! ( "{:?}" , c4 ) ;
}
@ -65,15 +77,24 @@ mod tests {
#[ test ]
fn test_tuple_out_of_range_positive ( ) {
assert! ( Color ::try_from ( ( 256 , 1000 , 10000 ) ) . is_err ( ) ) ;
assert_eq! (
Color ::try_from ( ( 256 , 1000 , 10000 ) ) ,
Err ( IntoColorError ::IntConversion )
) ;
}
#[ test ]
fn test_tuple_out_of_range_negative ( ) {
assert! ( Color ::try_from ( ( - 1 , - 10 , - 256 ) ) . is_err ( ) ) ;
assert_eq! (
Color ::try_from ( ( - 1 , - 10 , - 256 ) ) ,
Err ( IntoColorError ::IntConversion )
) ;
}
#[ test ]
fn test_tuple_sum ( ) {
assert! ( Color ::try_from ( ( - 1 , 255 , 255 ) ) . is_err ( ) ) ;
assert_eq! (
Color ::try_from ( ( - 1 , 255 , 255 ) ) ,
Err ( IntoColorError ::IntConversion )
) ;
}
#[ test ]
fn test_tuple_correct ( ) {
@ -91,17 +112,17 @@ mod tests {
#[ test ]
fn test_array_out_of_range_positive ( ) {
let c : Result < Color , _ > = [ 1000 , 10000 , 256 ] . try_into ( ) ;
assert !( c . is_err ( ) ) ;
assert _eq!( c , Err ( IntoColorError ::IntConversion ) ) ;
}
#[ test ]
fn test_array_out_of_range_negative ( ) {
let c : Result < Color , _ > = [ - 10 , - 256 , - 1 ] . try_into ( ) ;
assert !( c . is_err ( ) ) ;
assert _eq!( c , Err ( IntoColorError ::IntConversion ) ) ;
}
#[ test ]
fn test_array_sum ( ) {
let c : Result < Color , _ > = [ - 1 , 255 , 255 ] . try_into ( ) ;
assert !( c . is_err ( ) ) ;
assert _eq!( c , Err ( IntoColorError ::IntConversion ) ) ;
}
#[ test ]
fn test_array_correct ( ) {
@ -119,17 +140,26 @@ mod tests {
#[ test ]
fn test_slice_out_of_range_positive ( ) {
let arr = [ 10000 , 256 , 1000 ] ;
assert! ( Color ::try_from ( & arr [ .. ] ) . is_err ( ) ) ;
assert_eq! (
Color ::try_from ( & arr [ .. ] ) ,
Err ( IntoColorError ::IntConversion )
) ;
}
#[ test ]
fn test_slice_out_of_range_negative ( ) {
let arr = [ - 256 , - 1 , - 10 ] ;
assert! ( Color ::try_from ( & arr [ .. ] ) . is_err ( ) ) ;
assert_eq! (
Color ::try_from ( & arr [ .. ] ) ,
Err ( IntoColorError ::IntConversion )
) ;
}
#[ test ]
fn test_slice_sum ( ) {
let arr = [ - 1 , 255 , 255 ] ;
assert! ( Color ::try_from ( & arr [ .. ] ) . is_err ( ) ) ;
assert_eq! (
Color ::try_from ( & arr [ .. ] ) ,
Err ( IntoColorError ::IntConversion )
) ;
}
#[ test ]
fn test_slice_correct ( ) {
@ -148,11 +178,11 @@ mod tests {
#[ test ]
fn test_slice_excess_length ( ) {
let v = vec! [ 0 , 0 , 0 , 0 ] ;
assert !( Color ::try_from ( & v [ .. ] ) .is_err ( ) ) ;
assert _eq !( Color ::try_from ( & v [ .. ] ) , Err ( IntoColorError ::BadLen ) ) ;
}
#[ test ]
fn test_slice_insufficient_length ( ) {
let v = vec! [ 0 , 0 ] ;
assert !( Color ::try_from ( & v [ .. ] ) .is_err ( ) ) ;
assert _eq !( Color ::try_from ( & v [ .. ] ) , Err ( IntoColorError ::BadLen ) ) ;
}
}