Skip to content

Commit

Permalink
Rustlings for NaUKMA
Browse files Browse the repository at this point in the history
  • Loading branch information
KyrylSydorov committed Nov 18, 2024
1 parent adbbad6 commit 11a4568
Show file tree
Hide file tree
Showing 84 changed files with 428 additions and 218 deletions.
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

0 comments on commit 11a4568

Please sign in to comment.