From 9f4be26dc4fcb3889fb62dbde03c511698326f60 Mon Sep 17 00:00:00 2001 From: IkaR49 <IkaR49@users.noreply.github.com> Date: Tue, 12 May 2020 22:56:46 +0300 Subject: [PATCH] fix(try_from_into): Rewrite exercise Instead of working with strings, the exercise suggests creating a Color structure from other simple types (tuple, array, slice). closes #392 --- exercises/conversions/try_from_into.rs | 130 +++++++++++++------------ 1 file changed, 66 insertions(+), 64 deletions(-) diff --git a/exercises/conversions/try_from_into.rs b/exercises/conversions/try_from_into.rs index 9968075..fafa198 100644 --- a/exercises/conversions/try_from_into.rs +++ b/exercises/conversions/try_from_into.rs @@ -5,98 +5,100 @@ use std::convert::{TryInto, TryFrom}; #[derive(Debug)] -struct Person { - name: String, - age: usize, +struct Color { + red: u8, + green: u8, + blue: u8, } // I AM NOT DONE -// Your task is to complete this implementation -// in order for the line `let p = Person::try_from("Mark,20")` to compile -// and return an Ok result of inner type Person. -// Please note that you'll need to parse the age component into a `usize` -// with something like `"4".parse::<usize>()`. The outcome of this needs to -// be handled appropriately. -// -// Steps: -// 1. If the length of the provided string is 0, then return an error -// 2. Split the given string on the commas present in it -// 3. Extract the first element from the split operation and use it as the name -// 4. If the name is empty, then return an error. -// 5. Extract the other element from the split operation and parse it into a `usize` as the age -// If while parsing the age, something goes wrong, then return an error -// Otherwise, then return a Result of a Person object -impl TryFrom<&str> for Person { + +impl TryFrom<(i16, i16, i16)> for Color { type Error = String; - fn try_from(s: &str) -> Result<Self, Self::Error> { + fn try_from(tuple: (i16, i16, i16)) -> Result<Self, Self::Error> { + } +} + +impl TryFrom<[i16; 3]> for Color { + type Error = String; + fn try_from(arr: [i16; 3]) -> Result<Self, Self::Error> { + } +} + +impl TryFrom<&[i16]> for Color { + type Error = String; + fn try_from(slice: &[i16]) -> Result<Self, Self::Error> { } } fn main() { // Use the `from` function - let p1 = Person::try_from("Mark,20"); - // Since From is implemented for Person, we should be able to use Into - let p2: Result<Person, _> = "Gerald,70".try_into(); - println!("{:?}", p1); - println!("{:?}", p2); + let c1 = Color::try_from((183, 65, 14)); + println!("{:?}", c1); + + // Since From is implemented for Color, we should be able to use 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 + let c3 = Color::try_from(&v[..]); + println!("{:?}", c3); + // or take slice within round brackets + let c4: Result<Color, _> = (&v[..]).try_into(); + println!("{:?}", c4); } #[cfg(test)] mod tests { use super::*; - #[test] - fn test_bad_convert() { - // Test that error is returned when bad string is provided - let p = Person::try_from(""); - assert!(p.is_err()); - } - #[test] - fn test_good_convert() { - // Test that "Mark,20" works - let p = Person::try_from("Mark,20"); - assert!(p.is_ok()); - let p = p.unwrap(); - assert_eq!(p.name, "Mark"); - assert_eq!(p.age, 20); - } + #[test] #[should_panic] - fn test_panic_empty_input() { - let p: Person = "".try_into().unwrap(); + fn test_bad_tuple() { + let _: Color = Color::try_from((-1, 0, 0)).unwrap(); } #[test] - #[should_panic] - fn test_panic_bad_age() { - let p = Person::try_from("Mark,twenty").unwrap(); + fn test_good_tuple() { + let c: Color = (183, 65, 14).try_into().unwrap(); + assert_eq!(c.red, 183); + assert_eq!(c.green, 65); + assert_eq!(c.blue, 14); } #[test] #[should_panic] - fn test_missing_comma_and_age() { - let _: Person = "Mark".try_into().unwrap(); + fn test_bad_array() { + let _: Color = [0, -1, 0].try_into().unwrap(); + } + #[test] + fn test_good_array() { + let c: Color = [183, 65, 14].try_into().unwrap(); + + assert_eq!(c.red, 183); + assert_eq!(c.green, 65); + assert_eq!(c.blue, 14); } #[test] #[should_panic] - fn test_missing_age() { - let _: Person = "Mark,".try_into().unwrap(); + fn test_bad_slice() { + let arr = [0, 0, -1]; + let _ = Color::try_from(&arr[..]).unwrap(); } + #[test] + fn test_good_slice() { + let v = vec![183, 65, 14]; + let c = Color::try_from(&v[..]).unwrap(); + assert_eq!(c.red, 183); + assert_eq!(c.green, 65); + assert_eq!(c.blue, 14); + } #[test] #[should_panic] - fn test_missing_name() { - let _ : Person = ",1".try_into().unwrap(); + fn test_bad_slice_length() { + let v = vec![0, 0, 0, 0]; + let _ = Color::try_from(&v[..]).unwrap(); } - - #[test] - #[should_panic] - fn test_missing_name_and_age() { - let _: Person = ",".try_into().unwrap(); - } - - #[test] - #[should_panic] - fn test_missing_name_and_invalid_age() { - let _: Person = ",one".try_into().unwrap(); - } -} \ No newline at end of file +}