diff --git a/exercises/23_conversions/try_from_into.rs b/exercises/23_conversions/try_from_into.rs index f3ae80a..bf40cc9 100644 --- a/exercises/23_conversions/try_from_into.rs +++ b/exercises/23_conversions/try_from_into.rs @@ -6,6 +6,7 @@ #![allow(clippy::useless_vec)] use std::convert::{TryFrom, TryInto}; +use crate::IntoColorError::BadLen; #[derive(Debug, PartialEq)] struct Color { @@ -23,27 +24,60 @@ enum IntoColorError { IntConversion, } -// TODO: Tuple implementation. +// Tuple implementation. // Correct RGB color values must be integers in the 0..=255 range. impl TryFrom<(i16, i16, i16)> for Color { type Error = IntoColorError; - fn try_from(tuple: (i16, i16, i16)) -> Result {} + fn try_from(tuple: (i16, i16, i16)) -> Result { + let (red, green, blue) = tuple; + Self::from_rgb(red, green, blue) + } +} + +impl Color { + fn from_rgb(red: i16, green: i16, blue: i16) -> Result { + if red < 0 || red > 255 { + return Err(IntoColorError::IntConversion); + } + if blue < 0 || blue > 255 { + return Err(IntoColorError::IntConversion); + } + if green < 0 || green > 255 { + return Err(IntoColorError::IntConversion); + } + + Ok(Color { + red: red as u8, + green: green as u8, + blue: blue as u8 + }) + } } // TODO: Array implementation. impl TryFrom<[i16; 3]> for Color { type Error = IntoColorError; - fn try_from(arr: [i16; 3]) -> Result {} + fn try_from(arr: [i16; 3]) -> Result { + let [red, green, blue] = arr; + Self::from_rgb(red, green, blue) + } } -// TODO: Slice implementation. // This implementation needs to check the slice length. impl TryFrom<&[i16]> for Color { type Error = IntoColorError; - fn try_from(slice: &[i16]) -> Result {} + fn try_from(slice: &[i16]) -> Result { + if slice.len() != 3 { + return Err(BadLen) + } + let [red, green, blue] = *slice else { + return Err(BadLen) + }; + Self::from_rgb(red, green, blue) + } } fn main() {