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

Solution to 5.6.1 #1

Open
wants to merge 31 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
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
4 changes: 1 addition & 3 deletions exercises/clippy/clippy1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,10 @@
// Execute `rustlings hint clippy1` or use the `hint` watch subcommand for a
// hint.

// I AM NOT 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: 1 addition & 3 deletions exercises/clippy/clippy2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@
// Execute `rustlings hint clippy2` or use the `hint` watch subcommand for a
// hint.

// I AM NOT DONE

fn main() {
let mut res = 42;
let option = Some(12);
for x in option {
if let Option::Some(x) = option {
res += x;
}
println!("{}", res);
Expand Down
15 changes: 7 additions & 8 deletions exercises/clippy/clippy3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,27 @@
// Here's a couple more easy Clippy fixes, so you can see its utility.
// No hints.

// I AM NOT DONE

#[allow(unused_variables, unused_assignments)]
fn main() {
let my_option: Option<()> = None;
if my_option.is_none() {
my_option.unwrap();
// Do not access null content
// my_option.unwrap();
}

let my_arr = &[
-1, -2, -3
-4, -5, -6
-1, -2, -3,
-4, -5, -6,
];
println!("My array! Here it is: {:?}", my_arr);

let my_empty_vec = vec![1, 2, 3, 4, 5].resize(0, 5);
let mut my_empty_vec = vec![1, 2, 3, 4, 5];
my_empty_vec.clear();
println!("This Vec is empty, see? {:?}", my_empty_vec);

let mut value_a = 45;
let mut value_b = 66;
// Let's swap these two!
value_a = value_b;
value_b = value_a;
std::mem::swap(&mut value_a, &mut value_b);
println!("value a: {}; value b: {}", value_a, value_b);
}
29 changes: 20 additions & 9 deletions exercises/conversions/as_ref_mut.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,36 @@
// Execute `rustlings hint as_ref_mut` or use the `hint` watch subcommand for a
// hint.

// I AM NOT DONE
use std::ops::{Deref, Mul};

// Obtain the number of bytes (not characters) in the given argument.
// TODO: Add the AsRef trait appropriately as a trait bound.
fn byte_counter<T>(arg: T) -> usize {
// Add the AsRef trait appropriately as a trait bound.
fn byte_counter<T>(arg: T) -> usize
where
T: AsRef<str>,
{
arg.as_ref().as_bytes().len()
}

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

// Squares a number using as_mut().
// TODO: Add the appropriate trait bound.
fn num_sq<T>(arg: &mut T) {
// TODO: Implement the function body.
???
// Add the appropriate trait bound.
fn num_sq<T, TValue>(arg: &mut T)
where
T: AsMut<TValue>,
TValue: Mul<Output = TValue> + Copy,
{
// Implement the function body.
let mut x = arg.as_mut();
*x = (*x) * (*x);
}

#[cfg(test)]
Expand Down
40 changes: 38 additions & 2 deletions exercises/conversions/from_into.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,46 @@ 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 {
// Avoid using collect() to avoid unnecessary allocations
let mut it = s.split(',');

if let Some(name) = it.next().filter(|n| !n.is_empty()) {
if let Some(age) = it.next() {
if let Ok(age) = age.trim().parse::<usize>() {
return Person {
name: name.to_string(),
age,
};
}
}
}

Person::default()

// A common way with worse performance
// let splited: Vec<&str> = s.split(',').collect();

// if splited.len() < 2 {
// return Person::default();
// }

// let age = match splited[1].trim().parse::<usize>() {
// Ok(age) => age,
// Err(_) => return Person::default(),
// };

// let name = splited[0].to_string();

// if name.is_empty() {
// return Person::default();
// }

// Person {
// name,
// age,
// }
}
}

Expand Down
28 changes: 26 additions & 2 deletions exercises/conversions/from_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,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
Expand All @@ -52,6 +50,32 @@ enum ParsePersonError {
impl FromStr for Person {
type Err = ParsePersonError;
fn from_str(s: &str) -> Result<Person, Self::Err> {
if s.is_empty() {
return Err(ParsePersonError::Empty);
}

let mut it = s.split(',');

if let Some(name) = it.next() {
if name.is_empty() {
return Err(ParsePersonError::NoName);
}

if let Some(age) = it.next() {
let age = age.trim().parse::<usize>().map_err(ParsePersonError::ParseInt)?;

if it.next().is_none() {
return Ok(Person {
name: name.to_string(),
age,
});
}
}

return Err(ParsePersonError::BadLen);
}

Err(ParsePersonError::BadLen)
}
}

Expand Down
21 changes: 19 additions & 2 deletions exercises/conversions/try_from_into.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,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, an array of three integers, and a slice of integers.
Expand All @@ -41,20 +39,39 @@ enum IntoColorError {
impl TryFrom<(i16, i16, i16)> for Color {
type Error = IntoColorError;
fn try_from(tuple: (i16, i16, i16)) -> Result<Self, Self::Error> {
let (r, g, b) = tuple;

let r: u8 = r.try_into().map_err(|_| IntoColorError::IntConversion)?;
let g: u8 = g.try_into().map_err(|_| IntoColorError::IntConversion)?;
let b: u8 = b.try_into().map_err(|_| IntoColorError::IntConversion)?;

Ok(Color {
red: r,
green: g,
blue: b,
})
}
}

// Array implementation
impl TryFrom<[i16; 3]> for Color {
type Error = IntoColorError;
fn try_from(arr: [i16; 3]) -> Result<Self, Self::Error> {
let [r, g, b] = arr;

Color::try_from((r, g, b))
}
}

// 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);
}

Color::try_from((slice[0], slice[1], slice[2]))
}
}

Expand Down
4 changes: 1 addition & 3 deletions exercises/conversions/using_as.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,9 @@
// 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::<f64>();
total / values.len()
total / (values.len() as f64)
}

fn main() {
Expand Down
8 changes: 5 additions & 3 deletions exercises/enums/enums1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@
//
// No hints this time! ;)

// I AM NOT DONE

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

fn main() {
Expand Down
7 changes: 4 additions & 3 deletions exercises/enums/enums2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
// Execute `rustlings hint enums2` or use the `hint` watch subcommand for a
// hint.

// I AM NOT DONE

#[derive(Debug)]
enum Message {
// TODO: define the different variants used below
Move { x: i32, y: i32 },
Echo(String),
ChangeColor(u8, u8, u8),
Quit,
}

impl Message {
Expand Down
14 changes: 11 additions & 3 deletions exercises/enums/enums3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
// Execute `rustlings hint enums3` or use the `hint` watch subcommand for a
// hint.

// I AM NOT DONE

enum Message {
// TODO: implement the message variant types based on their usage below
// implement the message variant types based on their usage below
ChangeColor(u8, u8, u8),
Echo(String),
Move(Point),
Quit,
}

struct Point {
Expand Down Expand Up @@ -45,6 +47,12 @@ impl State {
// variants
// Remember: When passing a tuple as a function argument, you'll need
// extra parentheses: fn function((t, u, p, l, e))
match message {
Message::Quit => self.quit(),
Message::ChangeColor(r, g, b) => self.change_color((r, g, b)),
Message::Move(p) => self.move_position(p),
Message::Echo(msg) => self.echo(msg),
}
}
}

Expand Down
8 changes: 3 additions & 5 deletions exercises/error_handling/errors1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,12 @@
// Execute `rustlings hint errors1` or use the `hint` watch subcommand for a
// hint.

// I AM NOT DONE

pub fn generate_nametag_text(name: String) -> Option<String> {
pub fn generate_nametag_text(name: String) -> Result<String, String> {
if name.is_empty() {
// Empty names aren't allowed.
None
Result::Err(String::from("`name` was empty; it must be nonempty."))
} else {
Some(format!("Hi! My name is {}", name))
Result::Ok(format!("Hi! My name is {}", name))
}
}

Expand Down
41 changes: 37 additions & 4 deletions exercises/error_handling/errors2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,49 @@
// Execute `rustlings hint errors2` or use the `hint` watch subcommand for a
// hint.

// I AM NOT DONE

use std::num::ParseIntError;

pub fn total_cost(item_quantity: &str) -> Result<i32, ParseIntError> {
let processing_fee = 1;
let cost_per_item = 5;
let qty = item_quantity.parse::<i32>();

Ok(qty * cost_per_item + processing_fee)
{
// let qty = item_quantity.parse::<i32>();

// Ok(qty * cost_per_item + processing_fee)

// match qty {
// Result::Err(err) => Err(err),
// Result::Ok(qty) => Ok(qty * cost_per_item + processing_fee)
// }

// if let Result::Ok(qty) = qty {
// Ok(qty * cost_per_item + processing_fee)
// }
// else {
// qty
// }
}

// Original try! was discarded
{
// let qty = try!(item_quantity.parse::<i32>());

// Ok(qty * cost_per_item + processing_fee)
}

{
let qty = item_quantity.parse::<i32>()?;

Ok(qty * cost_per_item + processing_fee)
}

// I prefer this
// {
// let qty = item_quantity.parse::<i32>();

// qty.map(|qty| qty * cost_per_item + processing_fee)
// }
}

#[cfg(test)]
Expand Down
Loading