From 9b1f6c3cb2cdcd37e2ad397f78757437e1ac3c3d Mon Sep 17 00:00:00 2001 From: Austin Jones Date: Wed, 19 Jan 2022 16:26:28 -0500 Subject: [PATCH] done --- exercises/advanced_errors/advanced_errs1.rs | 11 +++- exercises/advanced_errors/advanced_errs2.rs | 19 +++++- exercises/clippy/clippy1.rs | 2 - exercises/clippy/clippy2.rs | 6 +- exercises/collections/vec1.rs | 4 +- exercises/collections/vec2.rs | 5 +- exercises/conversions/as_ref_mut.rs | 6 +- exercises/conversions/from_into.rs | 27 ++++++++- exercises/conversions/from_str.rs | 26 ++++++++- exercises/conversions/try_from_into.rs | 64 ++++++++++++++++++++- exercises/conversions/using_as.rs | 4 +- exercises/macros/macros1.rs | 4 +- exercises/macros/macros2.rs | 11 ++-- exercises/macros/macros3.rs | 5 +- exercises/macros/macros4.rs | 4 +- exercises/quiz4.rs | 11 +++- 16 files changed, 164 insertions(+), 45 deletions(-) diff --git a/exercises/advanced_errors/advanced_errs1.rs b/exercises/advanced_errors/advanced_errs1.rs index 4bc7b635..67817ead 100644 --- a/exercises/advanced_errors/advanced_errs1.rs +++ b/exercises/advanced_errors/advanced_errs1.rs @@ -7,8 +7,6 @@ // Make this code compile! Execute `rustlings hint advanced_errs1` for // hints :) -// I AM NOT DONE - use std::num::ParseIntError; use std::str::FromStr; @@ -24,6 +22,15 @@ impl From for ParsePosNonzeroError { fn from(e: CreationError) -> Self { // TODO: complete this implementation so that the `?` operator will // work for `CreationError` + ParsePosNonzeroError::Creation(e) + } +} + +impl From for ParsePosNonzeroError { + fn from(e: ParseIntError) -> Self { + // TODO: complete this implementation so that the `?` operator will + // work for `CreationError` + ParsePosNonzeroError::ParseInt(e) } } diff --git a/exercises/advanced_errors/advanced_errs2.rs b/exercises/advanced_errors/advanced_errs2.rs index d9d44d06..1c52ddb4 100644 --- a/exercises/advanced_errors/advanced_errs2.rs +++ b/exercises/advanced_errors/advanced_errs2.rs @@ -16,8 +16,6 @@ // 4. Complete the partial implementation of `Display` for // `ParseClimateError`. -// I AM NOT DONE - use std::error::Error; use std::fmt::{self, Display, Formatter}; use std::num::{ParseFloatError, ParseIntError}; @@ -47,11 +45,13 @@ impl From for ParseClimateError { impl From for ParseClimateError { fn from(e: ParseFloatError) -> Self { // TODO: Complete this function + Self::ParseFloat(e) } } // TODO: Implement a missing trait so that `main()` below will compile. It // is not necessary to implement any methods inside the missing trait. +impl Error for ParseClimateError {} // The `Display` trait allows for other code to obtain the error formatted // as a user-visible string. @@ -62,8 +62,11 @@ impl Display for ParseClimateError { // Imports the variants to make the following code more compact. use ParseClimateError::*; match self { + Empty => write!(f, "empty input"), NoCity => write!(f, "no city name"), + ParseInt(e) => write!(f, "error parsing year: {}", e), ParseFloat(e) => write!(f, "error parsing temperature: {}", e), + Badlen => write!(f, "incorrect number of fields"), _ => write!(f, "unhandled error!"), } } @@ -89,11 +92,21 @@ impl FromStr for Climate { // TODO: Complete this function by making it handle the missing error // cases. fn from_str(s: &str) -> Result { - let v: Vec<_> = s.split(',').collect(); + if s.len() == 0 { + return Err(ParseClimateError::Empty); + } + + let v: Vec<&str> = s.split(',').collect(); + let (city, year, temp) = match &v[..] { [city, year, temp] => (city.to_string(), year, temp), _ => return Err(ParseClimateError::BadLen), }; + + if city.len() == 0 { + return Err(ParseClimateError::NoCity); + } + let year: u32 = year.parse()?; let temp: f32 = temp.parse()?; Ok(Climate { city, year, temp }) diff --git a/exercises/clippy/clippy1.rs b/exercises/clippy/clippy1.rs index bdb5dd2c..2c150e10 100644 --- a/exercises/clippy/clippy1.rs +++ b/exercises/clippy/clippy1.rs @@ -6,8 +6,6 @@ // check clippy's suggestions from the output to solve the exercise. // Execute `rustlings hint clippy1` for hints :) -// I AM NOT DONE - fn main() { let x = 1.2331f64; let y = 1.2332f64; diff --git a/exercises/clippy/clippy2.rs b/exercises/clippy/clippy2.rs index 37af9ed0..161a1978 100644 --- a/exercises/clippy/clippy2.rs +++ b/exercises/clippy/clippy2.rs @@ -1,13 +1,13 @@ // clippy2.rs // Make me compile! Execute `rustlings hint clippy2` for hints :) -// I AM NOT DONE - fn main() { let mut res = 42; let option = Some(12); - for x in option { + + if let Some(x) = option { res += x; } + println!("{}", res); } diff --git a/exercises/collections/vec1.rs b/exercises/collections/vec1.rs index b144fb94..68287fe2 100644 --- a/exercises/collections/vec1.rs +++ b/exercises/collections/vec1.rs @@ -4,11 +4,9 @@ // Make me compile and pass the test! // Execute the command `rustlings hint vec1` if you need hints. -// I AM NOT DONE - fn array_and_vec() -> ([i32; 4], Vec) { let a = [10, 20, 30, 40]; // a plain array - let v = // TODO: declare your vector here with the macro for vectors + let v = vec![10, 20, 30, 40];// TODO: declare your vector here with the macro for vectors (a, v) } diff --git a/exercises/collections/vec2.rs b/exercises/collections/vec2.rs index 6595e401..e8405580 100644 --- a/exercises/collections/vec2.rs +++ b/exercises/collections/vec2.rs @@ -7,12 +7,9 @@ // Execute the command `rustlings hint vec2` if you need // hints. -// I AM NOT DONE - fn vec_loop(mut v: Vec) -> Vec { for i in v.iter_mut() { - // TODO: Fill this up so that each element in the Vec `v` is - // multiplied by 2. + *i = *i * 2 } // At this point, `v` should be equal to [4, 8, 12, 16, 20]. diff --git a/exercises/conversions/as_ref_mut.rs b/exercises/conversions/as_ref_mut.rs index 84f4a60c..f1e5072e 100644 --- a/exercises/conversions/as_ref_mut.rs +++ b/exercises/conversions/as_ref_mut.rs @@ -2,17 +2,15 @@ // Read more about them at https://doc.rust-lang.org/std/convert/trait.AsRef.html // and https://doc.rust-lang.org/std/convert/trait.AsMut.html, respectively. -// 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 { 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 { arg.as_ref().chars().count() } diff --git a/exercises/conversions/from_into.rs b/exercises/conversions/from_into.rs index 9d84174d..55cb527e 100644 --- a/exercises/conversions/from_into.rs +++ b/exercises/conversions/from_into.rs @@ -33,10 +33,33 @@ 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 { + if s.len() == 0 { + return Person::default(); + } + + let mut s = s.split(",").collect::>(); + + if s.len() != 2 { + return Person::default(); + } + + let name = s[0].to_string(); + + if name.len() <= 0 { + return Person::default() + } + + let age = match s[1].parse::() { + Ok(val) => val, + Err(_) => { return Person::default() }, + }; + + Person { + name, + age, + } } } diff --git a/exercises/conversions/from_str.rs b/exercises/conversions/from_str.rs index ece0b3cf..16bd32c8 100644 --- a/exercises/conversions/from_str.rs +++ b/exercises/conversions/from_str.rs @@ -26,8 +26,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 @@ -41,6 +39,30 @@ enum ParsePersonError { impl FromStr for Person { type Err = ParsePersonError; fn from_str(s: &str) -> Result { + if s.len() == 0 { + return Err(Self::Err::Empty); + } + + let mut s = s.split(",").collect::>(); + + if s.len() != 2 { + return Err(Self::Err::BadLen); + } + + let name = s[0].to_string(); + + if name.len() <= 0 { + return Err(Self::Err::NoName); + } + + let age = match s[1].parse::() { + Ok(val) => val, + Err(err) => { + return Err(Self::Err::ParseInt(err)); + } + }; + + Ok(Person { name, age }) } } diff --git a/exercises/conversions/try_from_into.rs b/exercises/conversions/try_from_into.rs index b8ec4455..5aad316d 100644 --- a/exercises/conversions/try_from_into.rs +++ b/exercises/conversions/try_from_into.rs @@ -21,8 +21,6 @@ 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, @@ -36,6 +34,25 @@ enum IntoColorError { impl TryFrom<(i16, i16, i16)> for Color { type Error = IntoColorError; fn try_from(tuple: (i16, i16, i16)) -> Result { + let red = if tuple.0 >= 0 && tuple.0 <= 255 { + tuple.0 as u8 + } else { + return Err(Self::Error::IntConversion); + }; + + let green = if tuple.1 >= 0 && tuple.1 <= 255 { + tuple.1 as u8 + } else { + return Err(Self::Error::IntConversion); + }; + + let blue = if tuple.2 >= 0 && tuple.2 <= 255 { + tuple.2 as u8 + } else { + return Err(Self::Error::IntConversion); + }; + + Ok(Color { red, green, blue }) } } @@ -43,6 +60,25 @@ impl TryFrom<(i16, i16, i16)> for Color { impl TryFrom<[i16; 3]> for Color { type Error = IntoColorError; fn try_from(arr: [i16; 3]) -> Result { + let red = if arr[0] >= 0 && arr[0] <= 255 { + arr[0] as u8 + } else { + return Err(Self::Error::IntConversion); + }; + + let green = if arr[1] >= 0 && arr[1] <= 255 { + arr[1] as u8 + } else { + return Err(Self::Error::IntConversion); + }; + + let blue = if arr[2] >= 0 && arr[2] <= 255 { + arr[2] as u8 + } else { + return Err(Self::Error::IntConversion); + }; + + Ok(Color { red, green, blue }) } } @@ -50,6 +86,30 @@ 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(Self::Error::BadLen); + } + + let red = if slice[0] >= 0 && slice[0] <= 255 { + slice[0] as u8 + } else { + return Err(Self::Error::IntConversion); + }; + + let green = if slice[1] >= 0 && slice[1] <= 255 { + slice[1] as u8 + } else { + return Err(Self::Error::IntConversion); + }; + + let blue = if slice[2] >= 0 && slice[2] <= 255 { + slice[2] as u8 + } else { + return Err(Self::Error::IntConversion); + }; + + Ok(Color { red, green, blue }) } } diff --git a/exercises/conversions/using_as.rs b/exercises/conversions/using_as.rs index 821309ec..f4a33ab4 100644 --- a/exercises/conversions/using_as.rs +++ b/exercises/conversions/using_as.rs @@ -5,11 +5,9 @@ // The goal is to make sure that the division does not fail to compile // and returns the proper type. -// I AM NOT DONE - fn average(values: &[f64]) -> f64 { let total = values.iter().fold(0.0, |a, b| a + b); - total / values.len() + total / values.len() as f64 } fn main() { diff --git a/exercises/macros/macros1.rs b/exercises/macros/macros1.rs index ed0dac85..de2584a5 100644 --- a/exercises/macros/macros1.rs +++ b/exercises/macros/macros1.rs @@ -1,8 +1,6 @@ // macros1.rs // Make me compile! Execute `rustlings hint macros1` for hints :) -// I AM NOT DONE - macro_rules! my_macro { () => { println!("Check out my macro!"); @@ -10,5 +8,5 @@ macro_rules! my_macro { } fn main() { - my_macro(); + my_macro!(); } diff --git a/exercises/macros/macros2.rs b/exercises/macros/macros2.rs index d0be1236..52cbfd82 100644 --- a/exercises/macros/macros2.rs +++ b/exercises/macros/macros2.rs @@ -1,14 +1,13 @@ // macros2.rs // Make me compile! Execute `rustlings hint macros2` for hints :) -// I AM NOT DONE - -fn main() { - my_macro!(); -} - macro_rules! my_macro { () => { println!("Check out my macro!"); }; } + +fn main() { + my_macro!(); +} + diff --git a/exercises/macros/macros3.rs b/exercises/macros/macros3.rs index 93a43113..e1473cef 100644 --- a/exercises/macros/macros3.rs +++ b/exercises/macros/macros3.rs @@ -2,14 +2,15 @@ // Make me compile, without taking the macro out of the module! // Execute `rustlings hint macros3` for hints :) -// I AM NOT DONE - mod macros { + #[macro_export] macro_rules! my_macro { () => { println!("Check out my macro!"); }; } + + pub(crate) use my_macro; } fn main() { diff --git a/exercises/macros/macros4.rs b/exercises/macros/macros4.rs index 3a748078..56930700 100644 --- a/exercises/macros/macros4.rs +++ b/exercises/macros/macros4.rs @@ -1,12 +1,10 @@ // macros4.rs // Make me compile! Execute `rustlings hint macros4` for hints :) -// I AM NOT DONE - macro_rules! my_macro { () => { println!("Check out my macro!"); - } + }; ($val:expr) => { println!("Look at this other macro: {}", $val); } diff --git a/exercises/quiz4.rs b/exercises/quiz4.rs index 6c47480d..ba4f07cd 100644 --- a/exercises/quiz4.rs +++ b/exercises/quiz4.rs @@ -5,7 +5,16 @@ // Write a macro that passes the quiz! No hints this time, you can do it! -// I AM NOT DONE +mod macros { + #[macro_export] + macro_rules! my_macro { + ($val:expr) => { + format!("Hello {}", $val) + }; + } + + pub(crate) use my_macro; +} #[cfg(test)] mod tests {