From 7ea2917f25a08de47eb9a55d038be3f95bbd5766 Mon Sep 17 00:00:00 2001 From: Karan Kadam Date: Wed, 28 Dec 2022 14:59:54 +1030 Subject: [PATCH] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20added=20solutions=20to?= =?UTF-8?q?=20conversions=20exercises?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- exercises/conversions/as_ref_mut.rs | 19 ++++++--- exercises/conversions/from_into.rs | 14 ++++++- exercises/conversions/from_str.rs | 22 ++++++++++- exercises/conversions/try_from_into.rs | 53 ++++++++++++++++++++------ exercises/conversions/using_as.rs | 4 +- 5 files changed, 87 insertions(+), 25 deletions(-) diff --git a/exercises/conversions/as_ref_mut.rs b/exercises/conversions/as_ref_mut.rs index 9f479739..d606cd37 100644 --- a/exercises/conversions/as_ref_mut.rs +++ b/exercises/conversions/as_ref_mut.rs @@ -3,24 +3,31 @@ // and https://doc.rust-lang.org/std/convert/trait.AsMut.html, respectively. // Execute `rustlings hint as_ref_mut` or use the `hint` watch subcommand for a hint. -// I AM NOT DONE - // Obtain the number of bytes (not characters) in the given argument // Add the AsRef trait appropriately as a trait bound -fn byte_counter(arg: T) -> usize { +fn byte_counter(arg: T) -> usize +where + T: AsRef, +{ arg.as_ref().as_bytes().len() } // Obtain the number of characters (not bytes) in the given argument // Add the AsRef trait appropriately as a trait bound -fn char_counter(arg: T) -> usize { +fn char_counter(arg: T) -> usize +where + T: AsRef, +{ arg.as_ref().chars().count() } // Squares a number using AsMut. Add the trait bound as is appropriate and // implement the function body. -fn num_sq(arg: &mut T) { - ??? +fn num_sq(arg: &mut T) +where + T: AsMut, +{ + *arg.as_mut() = *arg.as_mut() * *arg.as_mut(); } #[cfg(test)] diff --git a/exercises/conversions/from_into.rs b/exercises/conversions/from_into.rs index 6c272c3b..b78f2526 100644 --- a/exercises/conversions/from_into.rs +++ b/exercises/conversions/from_into.rs @@ -35,10 +35,20 @@ impl Default for Person { // If while parsing the age, something goes wrong, then return the default of Person // Otherwise, then return an instantiated Person object with the results -// I AM NOT DONE - impl From<&str> for Person { fn from(s: &str) -> Person { + let mut split = s.split(","); + let split_len = split.clone().count(); + let name = split.next().unwrap_or(""); + let age = split.next().unwrap_or("0").parse::().unwrap_or(0); + if name.len() == 0 || age == 0 || split_len != 2 { + Person::default() + } else { + Person { + name: name.to_string(), + age, + } + } } } diff --git a/exercises/conversions/from_str.rs b/exercises/conversions/from_str.rs index fe168159..88b3a4b0 100644 --- a/exercises/conversions/from_str.rs +++ b/exercises/conversions/from_str.rs @@ -28,8 +28,6 @@ enum ParsePersonError { ParseInt(ParseIntError), } -// I AM NOT DONE - // Steps: // 1. If the length of the provided string is 0, an error should be returned // 2. Split the given string on the commas present in it @@ -46,6 +44,26 @@ enum ParsePersonError { impl FromStr for Person { type Err = ParsePersonError; fn from_str(s: &str) -> Result { + if s.len() == 0 { + return Err(ParsePersonError::Empty); + } + let mut split = s.split(","); + let split_len = split.clone().count(); + if split_len != 2 { + return Err(ParsePersonError::BadLen); + } + let mut name = split.next().unwrap(); + let mut age = split.next().unwrap().parse::(); + if name.len() == 0 { + return Err(ParsePersonError::NoName); + } + if age.is_err() { + return Err(ParsePersonError::ParseInt(age.unwrap_err())); + } + Ok(Person { + name: name.to_string(), + age: age.unwrap(), + }) } } diff --git a/exercises/conversions/try_from_into.rs b/exercises/conversions/try_from_into.rs index fa98bc90..b7a05960 100644 --- a/exercises/conversions/try_from_into.rs +++ b/exercises/conversions/try_from_into.rs @@ -23,21 +23,16 @@ enum IntoColorError { 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. -// -// Note that the implementation for tuple and array will be checked at compile time, -// but the slice implementation needs to check the slice length! -// Also note that correct RGB color values must be integers in the 0..=255 range. - -// Tuple implementation impl TryFrom<(i16, i16, i16)> for Color { type Error = IntoColorError; fn try_from(tuple: (i16, i16, i16)) -> Result { + // extract values from tuple + let red = u8::try_from(tuple.0).map_err(|_| IntoColorError::IntConversion)?; + let green = u8::try_from(tuple.1).map_err(|_| IntoColorError::IntConversion)?; + let blue = u8::try_from(tuple.2).map_err(|_| IntoColorError::IntConversion)?; + + // return ok result + Ok(Color { red, green, blue }) } } @@ -45,6 +40,21 @@ impl TryFrom<(i16, i16, i16)> for Color { impl TryFrom<[i16; 3]> for Color { type Error = IntoColorError; fn try_from(arr: [i16; 3]) -> Result { + // Check for integer conversion error + let red = arr[0] + .try_into() + .map_err(|_| IntoColorError::IntConversion)?; + + let green = arr[1] + .try_into() + .map_err(|_| IntoColorError::IntConversion)?; + + let blue = arr[2] + .try_into() + .map_err(|_| IntoColorError::IntConversion)?; + + // return ok result + Ok(Color { red, green, blue }) } } @@ -52,6 +62,25 @@ impl TryFrom<[i16; 3]> for Color { impl TryFrom<&[i16]> for Color { type Error = IntoColorError; fn try_from(slice: &[i16]) -> Result { + if slice.len() != 3 { + return Err(IntoColorError::BadLen); + } + + // Check for integer conversion error + let red = slice[0] + .try_into() + .map_err(|_| IntoColorError::IntConversion)?; + + let green = slice[1] + .try_into() + .map_err(|_| IntoColorError::IntConversion)?; + + let blue = slice[2] + .try_into() + .map_err(|_| IntoColorError::IntConversion)?; + + // return ok result + Ok(Color { red, green, blue }) } } diff --git a/exercises/conversions/using_as.rs b/exercises/conversions/using_as.rs index 8c9b7113..0d961ca0 100644 --- a/exercises/conversions/using_as.rs +++ b/exercises/conversions/using_as.rs @@ -6,11 +6,9 @@ // and returns the proper type. // Execute `rustlings hint using_as` or use the `hint` watch subcommand for a hint. -// I AM NOT DONE - fn average(values: &[f64]) -> f64 { let total = values.iter().sum::(); - total / values.len() + total / values.len() as f64 } fn main() {