feat: 🎸 added solutions to conversions exercises

This commit is contained in:
Karan Kadam 2022-12-28 14:59:54 +10:30
parent 85ba2e3c7b
commit 7ea2917f25
5 changed files with 87 additions and 25 deletions

View File

@ -3,24 +3,31 @@
// and https://doc.rust-lang.org/std/convert/trait.AsMut.html, respectively. // 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. // 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 // Obtain the number of bytes (not characters) in the given argument
// Add the AsRef trait appropriately as a trait bound // Add the AsRef trait appropriately as a trait bound
fn byte_counter<T>(arg: T) -> usize { fn byte_counter<T>(arg: T) -> usize
where
T: AsRef<str>,
{
arg.as_ref().as_bytes().len() arg.as_ref().as_bytes().len()
} }
// Obtain the number of characters (not bytes) in the given argument // Obtain the number of characters (not bytes) in the given argument
// Add the AsRef trait appropriately as a trait bound // Add the AsRef trait appropriately as a trait bound
fn char_counter<T>(arg: T) -> usize { fn char_counter<T>(arg: T) -> usize
where
T: AsRef<str>,
{
arg.as_ref().chars().count() arg.as_ref().chars().count()
} }
// Squares a number using AsMut. Add the trait bound as is appropriate and // Squares a number using AsMut. Add the trait bound as is appropriate and
// implement the function body. // implement the function body.
fn num_sq<T>(arg: &mut T) { fn num_sq<T>(arg: &mut T)
??? where
T: AsMut<u32>,
{
*arg.as_mut() = *arg.as_mut() * *arg.as_mut();
} }
#[cfg(test)] #[cfg(test)]

View File

@ -35,10 +35,20 @@ impl Default for Person {
// If while parsing the age, something goes wrong, then return the default of 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 // Otherwise, then return an instantiated Person object with the results
// I AM NOT DONE
impl From<&str> for Person { impl From<&str> for Person {
fn from(s: &str) -> 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::<usize>().unwrap_or(0);
if name.len() == 0 || age == 0 || split_len != 2 {
Person::default()
} else {
Person {
name: name.to_string(),
age,
}
}
} }
} }

View File

@ -28,8 +28,6 @@ enum ParsePersonError {
ParseInt(ParseIntError), ParseInt(ParseIntError),
} }
// I AM NOT DONE
// Steps: // Steps:
// 1. If the length of the provided string is 0, an error should be returned // 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 // 2. Split the given string on the commas present in it
@ -46,6 +44,26 @@ enum ParsePersonError {
impl FromStr for Person { impl FromStr for Person {
type Err = ParsePersonError; type Err = ParsePersonError;
fn from_str(s: &str) -> Result<Person, Self::Err> { fn from_str(s: &str) -> Result<Person, Self::Err> {
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::<usize>();
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(),
})
} }
} }

View File

@ -23,21 +23,16 @@ enum IntoColorError {
IntConversion, 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 { impl TryFrom<(i16, i16, i16)> for Color {
type Error = IntoColorError; type Error = IntoColorError;
fn try_from(tuple: (i16, i16, i16)) -> Result<Self, Self::Error> { fn try_from(tuple: (i16, i16, i16)) -> Result<Self, Self::Error> {
// 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 { impl TryFrom<[i16; 3]> for Color {
type Error = IntoColorError; type Error = IntoColorError;
fn try_from(arr: [i16; 3]) -> Result<Self, Self::Error> { fn try_from(arr: [i16; 3]) -> Result<Self, Self::Error> {
// 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 { impl TryFrom<&[i16]> for Color {
type Error = IntoColorError; type Error = IntoColorError;
fn try_from(slice: &[i16]) -> Result<Self, Self::Error> { fn try_from(slice: &[i16]) -> Result<Self, Self::Error> {
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 })
} }
} }

View File

@ -6,11 +6,9 @@
// and returns the proper type. // and returns the proper type.
// Execute `rustlings hint using_as` or use the `hint` watch subcommand for a hint. // Execute `rustlings hint using_as` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE
fn average(values: &[f64]) -> f64 { fn average(values: &[f64]) -> f64 {
let total = values.iter().sum::<f64>(); let total = values.iter().sum::<f64>();
total / values.len() total / values.len() as f64
} }
fn main() { fn main() {