Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rustlings for NaUKMA #1

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion rustlings/exercises/advanced_errors/advanced_errs1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
// Make this code compile! Execute `rustlings hint advanced_errs1` for
// hints :)

// I AM NOT DONE
// I AM DONE

use std::num::ParseIntError;
use std::str::FromStr;
Expand All @@ -24,13 +24,20 @@ impl From<CreationError> for ParsePosNonzeroError {
fn from(e: CreationError) -> Self {
// TODO: complete this implementation so that the `?` operator will
// work for `CreationError`
ParsePosNonzeroError::Creation(e)
}
}

// TODO: implement another instance of the `From` trait here so that the
// `?` operator will work in the other place in the `FromStr`
// implementation below.

impl From<ParseIntError> for ParsePosNonzeroError {
fn from(e: ParseIntError) -> Self {
ParsePosNonzeroError::ParseInt(e)
}
}

// Don't change anything below this line.

impl FromStr for PositiveNonzeroInteger {
Expand Down
24 changes: 21 additions & 3 deletions rustlings/exercises/advanced_errors/advanced_errs2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
// 4. Complete the partial implementation of `Display` for
// `ParseClimateError`.

// I AM NOT DONE
// I AM DONE

use std::error::Error;
use std::fmt::{self, Display, Formatter};
Expand Down Expand Up @@ -46,12 +46,21 @@ impl From<ParseIntError> for ParseClimateError {
// `ParseFloatError` values.
impl From<ParseFloatError> 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 {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
ParseClimateError::ParseInt(e) => Some(e),
ParseClimateError::ParseFloat(e) => Some(e),
_ => None,
}
}
}

// The `Display` trait allows for other code to obtain the error formatted
// as a user-visible string.
Expand All @@ -61,9 +70,13 @@ impl Display for ParseClimateError {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
// Imports the variants to make the following code more compact.
use ParseClimateError::*;

match self {
NoCity => write!(f, "no city name"),
ParseFloat(e) => write!(f, "error parsing temperature: {}", e),
ParseInt(e) => write!(f, "error parsing year: {}", e),
Empty => write!(f, "empty input"),
BadLen => write!(f, "incorrect number of fields"),
}
}
}
Expand All @@ -88,11 +101,17 @@ impl FromStr for Climate {
// TODO: Complete this function by making it handle the missing error
// cases.
fn from_str(s: &str) -> Result<Self, Self::Err> {
if s.is_empty() {
return Err(ParseClimateError::Empty);
}
let v: Vec<_> = s.split(',').collect();
let (city, year, temp) = match &v[..] {
[city, year, temp] => (city.to_string(), year, temp),
_ => return Err(ParseClimateError::BadLen),
};
if city.is_empty() {
return Err(ParseClimateError::NoCity);
}
let year: u32 = year.parse()?;
let temp: f32 = temp.parse()?;
Ok(Climate { city, year, temp })
Expand Down Expand Up @@ -190,7 +209,6 @@ mod test {
);
}
#[test]
#[ignore]
fn test_downcast() {
let res = "São Paulo,-21,28.5".parse::<Climate>();
assert!(matches!(res, Err(ParseClimateError::ParseInt(_))));
Expand Down
4 changes: 2 additions & 2 deletions rustlings/exercises/clippy/clippy1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
// check clippy's suggestions from the output to solve the exercise.
// Execute `rustlings hint clippy1` for hints :)

// I AM NOT DONE
// I AM DONE

use std::f32;

fn main() {
let pi = 3.14f32;
let pi = f32::consts::PI;
let radius = 5.00f32;

let area = pi * f32::powi(radius, 2);
Expand Down
4 changes: 2 additions & 2 deletions rustlings/exercises/clippy/clippy2.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
// clippy2.rs
// Make me compile! Execute `rustlings hint clippy2` for hints :)

// I AM NOT DONE
// I AM DONE

fn main() {
let mut res = 42;
let option = Some(12);
for x in option {
if let Some(x) = option {
res += x;
}
println!("{}", res);
Expand Down
6 changes: 4 additions & 2 deletions rustlings/exercises/collections/hashmap1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,20 @@
// Execute the command `rustlings hint hashmap1` if you need
// hints.

// I AM NOT DONE
// I AM DONE

use std::collections::HashMap;

fn fruit_basket() -> HashMap<String, u32> {
let mut basket = // TODO: declare your hash map here.
let mut basket = HashMap::new();

// Two bananas are already given for you :)
basket.insert(String::from("banana"), 2);

// TODO: Put more fruits in your basket here.

basket.insert(String::from("apple"), 1);
basket.insert(String::from("orange"), 2);
basket
}

Expand Down
21 changes: 20 additions & 1 deletion rustlings/exercises/collections/hashmap2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// Execute the command `rustlings hint hashmap2` if you need
// hints.

// I AM NOT DONE
// I AM DONE

use std::collections::HashMap;

Expand All @@ -38,6 +38,25 @@ fn fruit_basket(basket: &mut HashMap<Fruit, u32>) {
// TODO: Put new fruits if not already present. Note that you
// are not allowed to put any type of fruit that's already
// present!
if !basket.contains_key(&fruit) {
match fruit {
Fruit::Apple => {
basket.insert(Fruit::Apple, 4);
}
Fruit::Mango => {
basket.insert(Fruit::Mango, 2);
}
Fruit::Lychee => {
basket.insert(Fruit::Lychee, 5);
}
Fruit::Banana => {
basket.insert(Fruit::Banana, 3);
}
Fruit::Pineapple => {
basket.insert(Fruit::Pineapple, 2);
}
}
}
}
}

Expand Down
4 changes: 2 additions & 2 deletions rustlings/exercises/collections/vec1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
// Make me compile and pass the test!
// Execute the command `rustlings hint vec1` if you need hints.

// I AM NOT DONE
// I AM DONE

fn array_and_vec() -> ([i32; 4], Vec<i32>) {
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];

(a, v)
}
Expand Down
4 changes: 2 additions & 2 deletions rustlings/exercises/collections/vec2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
// Execute the command `rustlings hint vec2` if you need
// hints.

// I AM NOT DONE
// I AM DONE

fn vec_loop(mut v: Vec<i32>) -> Vec<i32> {
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].
Expand Down
6 changes: 3 additions & 3 deletions rustlings/exercises/conversions/as_ref_mut.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@
// 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
// I AM DONE

// Obtain the number of bytes (not characters) in the given argument
// Add the AsRef trait appropriately as a trait bound
fn byte_counter<T>(arg: T) -> usize {
fn byte_counter<T: AsRef<str>>(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<T>(arg: T) -> usize {
fn char_counter<T: AsRef<str>>(arg: T) -> usize {
arg.as_ref().chars().count()
}

Expand Down
24 changes: 23 additions & 1 deletion rustlings/exercises/conversions/from_into.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,32 @@ 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
// I AM DONE

impl From<&str> for Person {
fn from(s: &str) -> Person {
if s.len() == 0 {
return Person::default();
}
let parts: Vec<&str> = s.split(',').collect();
let name = parts[0];
if name.len() == 0 {
return Person::default();
}
let age = match parts.get(1) {
Some(age) => age.parse::<usize>().unwrap_or(0),
None => 0,
};
if age == 0 {
return Person::default();
}
if parts.len() != 2 {
return Person::default();
}
Person {
name: name.to_string(),
age,
}
}
}

Expand Down
18 changes: 17 additions & 1 deletion rustlings/exercises/conversions/from_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ enum ParsePersonError {
ParseInt(ParseIntError),
}

// I AM NOT DONE
// I AM DONE

// Steps:
// 1. If the length of the provided string is 0, an error should be returned
Expand All @@ -41,6 +41,22 @@ enum ParsePersonError {
impl FromStr for Person {
type Err = ParsePersonError;
fn from_str(s: &str) -> Result<Person, Self::Err> {
if s.len() == 0 {
return Err(ParsePersonError::Empty);
}
let parts: Vec<&str> = s.split(',').collect();
if parts.len() != 2 {
return Err(ParsePersonError::BadLen);
}
let name = parts[0];
if name.len() == 0 {
return Err(ParsePersonError::NoName);
}
let age = parts[1].parse::<usize>().map_err(ParsePersonError::ParseInt)?;
Ok(Person {
name: name.to_string(),
age,
})
}
}

Expand Down
34 changes: 33 additions & 1 deletion rustlings/exercises/conversions/try_from_into.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ enum IntoColorError {
IntConversion,
}

// I AM NOT DONE
// I AM DONE

// Your task is to complete this implementation
// and return an Ok result of inner type Color.
Expand All @@ -36,20 +36,52 @@ enum IntoColorError {
impl TryFrom<(i16, i16, i16)> for Color {
type Error = IntoColorError;
fn try_from(tuple: (i16, i16, i16)) -> Result<Self, Self::Error> {
let (red, green, blue) = tuple;
if red < 0 || red > 255 || green < 0 || green > 255 || blue < 0 || blue > 255 {
return Err(IntoColorError::IntConversion);
}
Ok(Color {
red: red as u8,
green: green as u8,
blue: blue as u8,
})
}
}

// Array implementation
impl TryFrom<[i16; 3]> for Color {
type Error = IntoColorError;
fn try_from(arr: [i16; 3]) -> Result<Self, Self::Error> {
let [red, green, blue] = arr;
if red < 0 || red > 255 || green < 0 || green > 255 || blue < 0 || blue > 255 {
return Err(IntoColorError::IntConversion);
}
Ok(Color {
red: red as u8,
green: green as u8,
blue: blue as u8,
})
}
}

// Slice implementation
impl TryFrom<&[i16]> for Color {
type Error = IntoColorError;
fn try_from(slice: &[i16]) -> Result<Self, Self::Error> {
if slice.len() != 3 {
return Err(IntoColorError::BadLen);
}
let red = slice[0];
let green = slice[1];
let blue = slice[2];
if red < 0 || red > 255 || green < 0 || green > 255 || blue < 0 || blue > 255 {
return Err(IntoColorError::IntConversion);
}
Ok(Color {
red: red as u8,
green: green as u8,
blue: blue as u8,
})
}
}

Expand Down
4 changes: 2 additions & 2 deletions rustlings/exercises/conversions/using_as.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
// The goal is to make sure that the division does not fail to compile
// and returns the proper type.

// I AM NOT DONE
// I AM DONE

fn average(values: &[f64]) -> f64 {
let total = values.iter().sum::<f64>();
total / values.len()
total / values.len() as f64
}

fn main() {
Expand Down
7 changes: 5 additions & 2 deletions rustlings/exercises/enums/enums1.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
// enums1.rs
// Make me compile! Execute `rustlings hint enums1` for hints!

// I AM NOT DONE
// I AM DONE

#[derive(Debug)]
enum Message {
// TODO: define a few types of messages as used below
Quit,
Echo,
Move,
ChangeColor,
}

fn main() {
Expand Down
Loading