diff --git a/exercises/01_variables/variables1.rs b/exercises/01_variables/variables1.rs
index f83b44d..ec1bcac 100644
--- a/exercises/01_variables/variables1.rs
+++ b/exercises/01_variables/variables1.rs
@@ -1,6 +1,6 @@
fn main() {
// TODO: Add the missing keyword.
- x = 5;
+ let x = 5;
println!("x has the value {x}");
}
Exercicse 3
diff --git a/exercises/01_variables/variables2.rs b/exercises/01_variables/variables2.rs
index e2a3603..fb16c0b 100644
--- a/exercises/01_variables/variables2.rs
+++ b/exercises/01_variables/variables2.rs
@@ -1,6 +1,6 @@
fn main() {
// TODO: Change the line below to fix the compiler error.
- let x;
+ let x: i32 = 0;
if x == 10 {
println!("x is ten!");
Exercicse 4
diff --git a/exercises/01_variables/variables3.rs b/exercises/01_variables/variables3.rs
index 06f35bb..0ed3b38 100644
--- a/exercises/01_variables/variables3.rs
+++ b/exercises/01_variables/variables3.rs
@@ -1,6 +1,6 @@
fn main() {
// TODO: Change the line below to fix the compiler error.
- let x: i32;
+ let x: i32 = 0;
println!("Number {x}");
}
Exercicse 5
diff --git a/exercises/01_variables/variables4.rs b/exercises/01_variables/variables4.rs
index 6c138b1..90d4ef0 100644
--- a/exercises/01_variables/variables4.rs
+++ b/exercises/01_variables/variables4.rs
@@ -1,6 +1,6 @@
// TODO: Fix the compiler error.
fn main() {
- let x = 3;
+ let mut x = 3;
println!("Number {x}");
x = 5; // Don't change this line
Exercicse 6
diff --git a/exercises/01_variables/variables5.rs b/exercises/01_variables/variables5.rs
index cf5620d..085e099 100644
--- a/exercises/01_variables/variables5.rs
+++ b/exercises/01_variables/variables5.rs
@@ -3,6 +3,6 @@ fn main() {
println!("Spell a number: {number}");
// TODO: Fix the compiler error by changing the line below without renaming the variable.
- number = 3;
+ let number = 3;
println!("Number plus two is: {}", number + 2);
}
Exercicse 7
diff --git a/exercises/01_variables/variables6.rs b/exercises/01_variables/variables6.rs
index 4a040fd..deb33ed 100644
--- a/exercises/01_variables/variables6.rs
+++ b/exercises/01_variables/variables6.rs
@@ -1,5 +1,5 @@
// TODO: Change the line below to fix the compiler error.
-const NUMBER = 3;
+const NUMBER: i32 = 3;
fn main() {
println!("Number: {NUMBER}");
Exercicse 8
diff --git a/exercises/02_functions/functions1.rs b/exercises/02_functions/functions1.rs
index a812c21..2534ec1 100644
--- a/exercises/02_functions/functions1.rs
+++ b/exercises/02_functions/functions1.rs
@@ -1,4 +1,5 @@
// TODO: Add some function with the name `call_me` without arguments or a return value.
+fn call_me() {}
fn main() {
call_me(); // Don't change this line
Exercicse 9
diff --git a/exercises/02_functions/functions2.rs b/exercises/02_functions/functions2.rs
index 2c773c6..325b45d 100644
--- a/exercises/02_functions/functions2.rs
+++ b/exercises/02_functions/functions2.rs
@@ -1,5 +1,5 @@
// TODO: Add the missing type of the argument `num` after the colon `:`.
-fn call_me(num:) {
+fn call_me(num: u8) {
for i in 0..num {
println!("Ring! Call number {}", i + 1);
}
diff --git a/exercises/02_functions/functions5.rs b/exercises/02_functions/functions5.rs
index 34a2ac7..a063100 100644
--- a/exercises/02_functions/functions5.rs
+++ b/exercises/02_functions/functions5.rs
@@ -1,6 +1,6 @@
// TODO: Fix the function body without changing the signature.
fn square(num: i32) -> i32 {
- num * num;
+ num * num
}
fn main() {
Exercicse 13
diff --git a/exercises/03_if/if1.rs b/exercises/03_if/if1.rs
index e5a3c5a..8036c89 100644
--- a/exercises/03_if/if1.rs
+++ b/exercises/03_if/if1.rs
@@ -4,6 +4,7 @@ fn bigger(a: i32, b: i32) -> i32 {
// Do not use:
// - another function call
// - additional variables
+ if a > b { a } else { b }
}
fn main() {
Exercicse 14
diff --git a/exercises/03_if/if2.rs b/exercises/03_if/if2.rs
index ca8493c..8104487 100644
--- a/exercises/03_if/if2.rs
+++ b/exercises/03_if/if2.rs
@@ -2,8 +2,10 @@
fn picky_eater(food: &str) -> &str {
if food == "strawberry" {
"Yummy!"
+ } else if food == "potato" {
+ "I guess I can eat that."
} else {
- 1
+ "No thanks!"
}
}
diff --git a/exercises/04_primitive_types/primitive_types1.rs b/exercises/04_primitive_types/primitive_types1.rs
index 84923c7..f7bc175 100644
--- a/exercises/04_primitive_types/primitive_types1.rs
+++ b/exercises/04_primitive_types/primitive_types1.rs
@@ -8,7 +8,7 @@ fn main() {
// TODO: Define a boolean variable with the name `is_evening` before the `if` statement below.
// The value of the variable should be the negation (opposite) of `is_morning`.
- // let …
+ let is_evening: bool = true;
if is_evening {
println!("Good evening!");
}
Exercicse 17
diff --git a/exercises/04_primitive_types/primitive_types2.rs b/exercises/04_primitive_types/primitive_types2.rs
index 1401847..d14254c 100644
--- a/exercises/04_primitive_types/primitive_types2.rs
+++ b/exercises/04_primitive_types/primitive_types2.rs
@@ -16,7 +16,7 @@ fn main() {
// below with your favorite character.
// Try a letter, try a digit (in single quotes), try a special character, try a character
// from a different language than your own, try an emoji 😉
- // let your_character = '';
+ let your_character = 'a';
if your_character.is_alphabetic() {
println!("Alphabetical!");
Exercicse 18
diff --git a/exercises/04_primitive_types/primitive_types3.rs b/exercises/04_primitive_types/primitive_types3.rs
index 9b79c0c..4abdbfe 100644
--- a/exercises/04_primitive_types/primitive_types3.rs
+++ b/exercises/04_primitive_types/primitive_types3.rs
@@ -1,6 +1,6 @@
fn main() {
// TODO: Create an array called `a` with at least 100 elements in it.
- // let a = ???
+ let a = [0; 100];
if a.len() >= 100 {
println!("Wow, that's a big array!");
Exercicse 19
diff --git a/exercises/04_primitive_types/primitive_types4.rs b/exercises/04_primitive_types/primitive_types4.rs
index 16e4fd9..1d70319 100644
--- a/exercises/04_primitive_types/primitive_types4.rs
+++ b/exercises/04_primitive_types/primitive_types4.rs
@@ -9,7 +9,7 @@ mod tests {
let a = [1, 2, 3, 4, 5];
// TODO: Get a slice called `nice_slice` out of the array `a` so that the test passes.
- // let nice_slice = ???
+ let nice_slice = &a[1..a.len() - 1];
assert_eq!([2, 3, 4], nice_slice);
}
Exercicse 20
diff --git a/exercises/04_primitive_types/primitive_types5.rs b/exercises/04_primitive_types/primitive_types5.rs
index 6e00ef5..9be20b0 100644
--- a/exercises/04_primitive_types/primitive_types5.rs
+++ b/exercises/04_primitive_types/primitive_types5.rs
@@ -2,7 +2,7 @@ fn main() {
let cat = ("Furry McFurson", 3.5);
// TODO: Destructure the `cat` tuple in one statement so that the println works.
- // let /* your pattern here */ = cat;
+ let (name, age) = (cat.0, cat.1);
println!("{name} is {age} years old");
}
Exercicse 21
diff --git a/exercises/04_primitive_types/primitive_types6.rs b/exercises/04_primitive_types/primitive_types6.rs
index a97e531..e70cb69 100644
--- a/exercises/04_primitive_types/primitive_types6.rs
+++ b/exercises/04_primitive_types/primitive_types6.rs
@@ -10,7 +10,7 @@ mod tests {
// TODO: Use a tuple index to access the second element of `numbers`
// and assign it to a variable called `second`.
- // let second = ???;
+ let second = numbers.1;
assert_eq!(second, 2, "This is not the 2nd number in the tuple!");
}
Exercicse 22
diff --git a/exercises/05_vecs/vecs1.rs b/exercises/05_vecs/vecs1.rs
index 68e1aff..f88b702 100644
--- a/exercises/05_vecs/vecs1.rs
+++ b/exercises/05_vecs/vecs1.rs
@@ -3,7 +3,7 @@ fn array_and_vec() -> ([i32; 4], Vec<i32>) {
// TODO: Create a vector called `v` which contains the exact same elements as in the array `a`.
// Use the vector macro.
- // let v = ???;
+ let v = a.to_vec();
(a, v)
}
Exercicse 23
diff --git a/exercises/05_vecs/vecs2.rs b/exercises/05_vecs/vecs2.rs
index a9be258..3466ed2 100644
--- a/exercises/05_vecs/vecs2.rs
+++ b/exercises/05_vecs/vecs2.rs
@@ -2,8 +2,7 @@ fn vec_loop(input: &[i32]) -> Vec<i32> {
let mut output = Vec::new();
for element in input {
- // TODO: Multiply each element in the `input` slice by 2 and push it to
- // the `output` vector.
+ output.push(element * 2);
}
output
@@ -21,12 +20,7 @@ fn vec_map(input: &[i32]) -> Vec<i32> {
// by 2, but with iterator mapping instead of manually pushing into an empty
// vector.
// See the example in the function `vec_map_example` above.
- input
- .iter()
- .map(|element| {
- // ???
- })
- .collect()
+ input.iter().map(|element| element * 2).collect()
}
fn main() {
Exercicse 24
diff --git a/exercises/06_move_semantics/move_semantics1.rs b/exercises/06_move_semantics/move_semantics1.rs
index 4eb3d61..bf55943 100644
--- a/exercises/06_move_semantics/move_semantics1.rs
+++ b/exercises/06_move_semantics/move_semantics1.rs
@@ -1,6 +1,6 @@
// TODO: Fix the compiler error in this function.
fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
- let vec = vec;
+ let mut vec = vec;
vec.push(88);
diff --git a/exercises/06_move_semantics/move_semantics3.rs b/exercises/06_move_semantics/move_semantics3.rs
index 11dbbbe..4a90c21 100644
--- a/exercises/06_move_semantics/move_semantics3.rs
+++ b/exercises/06_move_semantics/move_semantics3.rs
@@ -1,5 +1,5 @@
// TODO: Fix the compiler error in the function without adding any new line.
-fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
+fn fill_vec(mut vec: Vec<i32>) -> Vec<i32> {
vec.push(88);
vec
Exercicse 27
diff --git a/exercises/06_move_semantics/move_semantics4.rs b/exercises/06_move_semantics/move_semantics4.rs
index 56da988..89b412f 100644
--- a/exercises/06_move_semantics/move_semantics4.rs
+++ b/exercises/06_move_semantics/move_semantics4.rs
@@ -10,8 +10,8 @@ mod tests {
fn move_semantics4() {
let mut x = Vec::new();
let y = &mut x;
- let z = &mut x;
y.push(42);
+ let z = &mut x;
z.push(13);
assert_eq!(x, [42, 13]);
}
Exercicse 28
diff --git a/exercises/06_move_semantics/move_semantics5.rs b/exercises/06_move_semantics/move_semantics5.rs
index cd0dafd..78d8c77 100644
--- a/exercises/06_move_semantics/move_semantics5.rs
+++ b/exercises/06_move_semantics/move_semantics5.rs
@@ -4,12 +4,12 @@
// removing references (the character `&`).
// Shouldn't take ownership
-fn get_char(data: String) -> char {
+fn get_char(data: &String) -> char {
data.chars().last().unwrap()
}
// Should take ownership
-fn string_uppercase(mut data: &String) {
+fn string_uppercase(mut data: String) {
data = data.to_uppercase();
println!("{data}");
@@ -18,7 +18,7 @@ fn string_uppercase(mut data: &String) {
fn main() {
let data = "Rust is great!".to_string();
- get_char(data);
+ get_char(&data);
- string_uppercase(&data);
+ string_uppercase(data);
}
Exercicse 29
diff --git a/exercises/07_structs/structs1.rs b/exercises/07_structs/structs1.rs
index 959c4c6..06bfd50 100644
--- a/exercises/07_structs/structs1.rs
+++ b/exercises/07_structs/structs1.rs
@@ -1,9 +1,12 @@
struct ColorRegularStruct {
// TODO: Add the fields that the test `regular_structs` expects.
// What types should the fields have? What are the minimum and maximum values for RGB colors?
+ red: u8,
+ green: u8,
+ blue: u8,
}
-struct ColorTupleStruct(/* TODO: Add the fields that the test `tuple_structs` expects */);
+struct ColorTupleStruct(u8, u8, u8);
#[derive(Debug)]
struct UnitStruct;
@@ -19,7 +22,11 @@ mod tests {
#[test]
fn regular_structs() {
// TODO: Instantiate a regular struct.
- // let green =
+ let green = ColorRegularStruct {
+ red: 0,
+ green: 255,
+ blue: 0,
+ };
assert_eq!(green.red, 0);
assert_eq!(green.green, 255);
@@ -29,7 +36,7 @@ mod tests {
#[test]
fn tuple_structs() {
// TODO: Instantiate a tuple struct.
- // let green =
+ let green = ColorTupleStruct(0, 255, 0);
assert_eq!(green.0, 0);
assert_eq!(green.1, 255);
@@ -39,7 +46,7 @@ mod tests {
#[test]
fn unit_structs() {
// TODO: Instantiate a unit struct.
- // let unit_struct =
+ let unit_struct = UnitStruct;
let message = format!("{unit_struct:?}s are fun!");
assert_eq!(message, "UnitStructs are fun!");
Exercicse 30
diff --git a/exercises/07_structs/structs2.rs b/exercises/07_structs/structs2.rs
index 79141af..eb18715 100644
--- a/exercises/07_structs/structs2.rs
+++ b/exercises/07_structs/structs2.rs
@@ -34,7 +34,11 @@ mod tests {
let order_template = create_order_template();
// TODO: Create your own order using the update syntax and template above!
- // let your_order =
+ let your_order = Order {
+ name: String::from("Hacker in Rust"),
+ count: 1,
+ ..order_template
+ };
assert_eq!(your_order.name, "Hacker in Rust");
assert_eq!(your_order.year, order_template.year);
Exercicse 31
diff --git a/exercises/07_structs/structs3.rs b/exercises/07_structs/structs3.rs
index 69e5ced..6d1cd27 100644
--- a/exercises/07_structs/structs3.rs
+++ b/exercises/07_structs/structs3.rs
@@ -24,14 +24,13 @@ impl Package {
}
// TODO: Add the correct return type to the function signature.
- fn is_international(&self) {
- // TODO: Read the tests that use this method to find out when a package
- // is considered international.
+ fn is_international(&self) -> bool {
+ self.sender_country != self.recipient_country
}
// TODO: Add the correct return type to the function signature.
- fn get_fees(&self, cents_per_gram: u32) {
- // TODO: Calculate the package's fees.
+ fn get_fees(&self, cents_per_gram: u32) -> u32 {
+ self.weight_in_grams * cents_per_gram
}
}
Exercicse 32
diff --git a/exercises/08_enums/enums1.rs b/exercises/08_enums/enums1.rs
index c0d0c30..97a5cc0 100644
--- a/exercises/08_enums/enums1.rs
+++ b/exercises/08_enums/enums1.rs
@@ -1,6 +1,10 @@
#[derive(Debug)]
enum Message {
- // TODO: Define a few types of messages as used below.
+ Resize,
+ Move,
+ Echo,
+ ChangeColor,
+ Quit,
}
fn main() {
diff --git a/exercises/08_enums/enums3.rs b/exercises/08_enums/enums3.rs
index cb05f65..abacb51 100644
--- a/exercises/08_enums/enums3.rs
+++ b/exercises/08_enums/enums3.rs
@@ -1,3 +1,5 @@
+use crate::Message::Resize;
+
struct Point {
x: u64,
y: u64,
@@ -44,8 +46,13 @@ impl State {
}
fn process(&mut self, message: Message) {
- // TODO: Create a match expression to process the different message
- // variants using the methods defined above.
+ match message {
+ Message::Resize { width, height } => self.resize(width, height),
+ Message::Move(pos) => self.move_position(pos),
+ Message::Echo(msg) => self.echo(msg),
+ Message::ChangeColor(r, g, b) => self.change_color(r, g, b),
+ Message::Quit => self.quit(),
+ }
}
}
Exercicse 35
diff --git a/exercises/09_strings/strings1.rs b/exercises/09_strings/strings1.rs
index 6abdbb4..9ff1641 100644
--- a/exercises/09_strings/strings1.rs
+++ b/exercises/09_strings/strings1.rs
@@ -1,6 +1,6 @@
// TODO: Fix the compiler error without changing the function signature.
fn current_favorite_color() -> String {
- "blue"
+ String::from("blue")
}
fn main() {
Exercicse 36
diff --git a/exercises/09_strings/strings2.rs b/exercises/09_strings/strings2.rs
index 93d9cb6..2ed89c5 100644
--- a/exercises/09_strings/strings2.rs
+++ b/exercises/09_strings/strings2.rs
@@ -6,7 +6,7 @@ fn is_a_color_word(attempt: &str) -> bool {
fn main() {
let word = String::from("green"); // Don't change this line.
- if is_a_color_word(word) {
+ if is_a_color_word(&word) {
println!("That is a color word I know!");
} else {
println!("That is not a color word I know.");
Exercicse 37
diff --git a/exercises/09_strings/strings3.rs b/exercises/09_strings/strings3.rs
index f5e45b0..5fcc656 100644
--- a/exercises/09_strings/strings3.rs
+++ b/exercises/09_strings/strings3.rs
@@ -1,13 +1,16 @@
fn trim_me(input: &str) -> &str {
// TODO: Remove whitespace from both ends of a string.
+ input.trim()
}
fn compose_me(input: &str) -> String {
// TODO: Add " world!" to the string! There are multiple ways to do this.
+ String::from(input) + &String::from(" world!")
}
fn replace_me(input: &str) -> String {
// TODO: Replace "cars" in the string with "balloons".
+ input.replace("cars", "balloons")
}
fn main() {
Exercicse 38
diff --git a/exercises/09_strings/strings4.rs b/exercises/09_strings/strings4.rs
index 4730726..3f7c5e7 100644
--- a/exercises/09_strings/strings4.rs
+++ b/exercises/09_strings/strings4.rs
@@ -13,25 +13,25 @@ fn string(arg: String) {
// Your task is to replace `placeholder(…)` with either `string_slice(…)`
// or `string(…)` depending on what you think each value is.
fn main() {
- placeholder("blue");
+ string_slice("blue");
- placeholder("red".to_string());
+ string("red".to_string());
- placeholder(String::from("hi"));
+ string(String::from("hi"));
- placeholder("rust is fun!".to_owned());
+ string("rust is fun!".to_owned());
- placeholder("nice weather".into());
+ string("nice weather".into());
- placeholder(format!("Interpolation {}", "Station"));
+ string(format!("Interpolation {}", "Station"));
// WARNING: This is byte indexing, not character indexing.
// Character indexing can be done using `s.chars().nth(INDEX)`.
- placeholder(&String::from("abc")[0..1]);
+ string_slice(&String::from("abc")[0..1]);
- placeholder(" hello there ".trim());
+ string_slice(" hello there ".trim());
- placeholder("Happy Monday!".replace("Mon", "Tues"));
+ string("Happy Monday!".replace("Mon", "Tues"));
- placeholder("mY sHiFt KeY iS sTiCkY".to_lowercase());
+ string("mY sHiFt KeY iS sTiCkY".to_lowercase());
}
diff --git a/exercises/10_modules/modules2.rs b/exercises/10_modules/modules2.rs
index 782a70e..3cabbfd 100644
--- a/exercises/10_modules/modules2.rs
+++ b/exercises/10_modules/modules2.rs
@@ -3,8 +3,8 @@
mod delicious_snacks {
// TODO: Add the following two `use` statements after fixing them.
- // use self::fruits::PEAR as ???;
- // use self::veggies::CUCUMBER as ???;
+ pub use self::fruits::PEAR as fruit;
+ pub use self::veggies::CUCUMBER as veggie;
mod fruits {
pub const PEAR: &str = "Pear";
Exercicse 41
diff --git a/exercises/10_modules/modules3.rs b/exercises/10_modules/modules3.rs
index 691608d..403b7ea 100644
--- a/exercises/10_modules/modules3.rs
+++ b/exercises/10_modules/modules3.rs
@@ -3,7 +3,7 @@
// TODO: Bring `SystemTime` and `UNIX_EPOCH` from the `std::time` module into
// your scope. Bonus style points if you can do it with one line!
-// use ???;
+use std::time::{SystemTime, UNIX_EPOCH};
fn main() {
match SystemTime::now().duration_since(UNIX_EPOCH) {
Exercicse 42
diff --git a/exercises/11_hashmaps/hashmaps1.rs b/exercises/11_hashmaps/hashmaps1.rs
index 74001d0..f5b82f4 100644
--- a/exercises/11_hashmaps/hashmaps1.rs
+++ b/exercises/11_hashmaps/hashmaps1.rs
@@ -8,13 +8,18 @@ use std::collections::HashMap;
fn fruit_basket() -> HashMap<String, u32> {
// TODO: Declare the hash map.
- // let mut basket =
+ 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.
+ basket.insert(String::from("apple"), 3);
+ basket.insert(String::from("mango"), 4);
+ basket.insert(String::from("orange"), 5);
+ basket.insert(String::from("kiwi"), 6);
+
basket
}
Exercicse 43
diff --git a/exercises/11_hashmaps/hashmaps2.rs b/exercises/11_hashmaps/hashmaps2.rs
index e9f53fe..adfc478 100644
--- a/exercises/11_hashmaps/hashmaps2.rs
+++ b/exercises/11_hashmaps/hashmaps2.rs
@@ -29,9 +29,7 @@ fn fruit_basket(basket: &mut HashMap<Fruit, u32>) {
];
for fruit in fruit_kinds {
- // TODO: Insert new fruits if they are not already present in the
- // basket. Note that you are not allowed to put any type of fruit that's
- // already present!
+ basket.entry(fruit).or_insert(5);
}
}
Exercicse 44
diff --git a/exercises/11_hashmaps/hashmaps3.rs b/exercises/11_hashmaps/hashmaps3.rs
index 5b390ab..3c38bf7 100644
--- a/exercises/11_hashmaps/hashmaps3.rs
+++ b/exercises/11_hashmaps/hashmaps3.rs
@@ -31,6 +31,13 @@ fn build_scores_table(results: &str) -> HashMap<&str, TeamScores> {
// Keep in mind that goals scored by team 1 will be the number of goals
// conceded by team 2. Similarly, goals scored by team 2 will be the
// number of goals conceded by team 1.
+ let team_1 = scores.entry(team_1_name).or_default();
+ team_1.goals_scored += team_1_score;
+ team_1.goals_conceded += team_2_score;
+
+ let team_2 = scores.entry(team_2_name).or_default();
+ team_2.goals_scored += team_2_score;
+ team_2.goals_conceded += team_1_score;
}
scores
@@ -54,9 +61,11 @@ England,Spain,1,0";
fn build_scores() {
let scores = build_scores_table(RESULTS);
- assert!(["England", "France", "Germany", "Italy", "Poland", "Spain"]
- .into_iter()
- .all(|team_name| scores.contains_key(team_name)));
+ assert!(
+ ["England", "France", "Germany", "Italy", "Poland", "Spain"]
+ .into_iter()
+ .all(|team_name| scores.contains_key(team_name))
+ );
}
#[test]
Exercicse 45
diff --git a/exercises/12_options/options1.rs b/exercises/12_options/options1.rs
index d0c412a..f501de8 100644
--- a/exercises/12_options/options1.rs
+++ b/exercises/12_options/options1.rs
@@ -3,7 +3,11 @@
// someone eats it all, so no ice cream is left (value 0). Return `None` if
// `hour_of_day` is higher than 23.
fn maybe_ice_cream(hour_of_day: u16) -> Option<u16> {
- // TODO: Complete the function body.
+ match hour_of_day {
+ 0..=21 => Some(5),
+ 22..=23 => Some(0),
+ _ => None,
+ }
}
fn main() {
@@ -18,7 +22,7 @@ mod tests {
fn raw_value() {
// TODO: Fix this test. How do you get the value contained in the
// Option?
- let ice_creams = maybe_ice_cream(12);
+ let ice_creams = maybe_ice_cream(12).unwrap();
assert_eq!(ice_creams, 5); // Don't change this line.
}
Exercicse 46
diff --git a/exercises/12_options/options2.rs b/exercises/12_options/options2.rs
index 07c27c6..1039d61 100644
--- a/exercises/12_options/options2.rs
+++ b/exercises/12_options/options2.rs
@@ -10,7 +10,7 @@ mod tests {
let optional_target = Some(target);
// TODO: Make this an if-let statement whose value is `Some`.
- word = optional_target {
+ if let Some(word) = optional_target {
assert_eq!(word, target);
}
}
@@ -29,7 +29,7 @@ mod tests {
// TODO: Make this a while-let statement. Remember that `Vec::pop()`
// adds another layer of `Option`. You can do nested pattern matching
// in if-let and while-let statements.
- integer = optional_integers.pop() {
+ while let Some(Some(integer)) = optional_integers.pop() {
assert_eq!(integer, cursor);
cursor -= 1;
}
Exercicse 47
diff --git a/exercises/12_options/options3.rs b/exercises/12_options/options3.rs
index c97b1d3..aecb7a5 100644
--- a/exercises/12_options/options3.rs
+++ b/exercises/12_options/options3.rs
@@ -9,7 +9,7 @@ fn main() {
// TODO: Fix the compiler error by adding something to this match statement.
match optional_point {
- Some(p) => println!("Coordinates are {},{}", p.x, p.y),
+ Some(ref p) => println!("Coordinates are {},{}", p.x, p.y),
_ => panic!("No match!"),
}
Exercicse 48
diff --git a/exercises/13_error_handling/errors1.rs b/exercises/13_error_handling/errors1.rs
index e07fddc..0cced95 100644
--- a/exercises/13_error_handling/errors1.rs
+++ b/exercises/13_error_handling/errors1.rs
@@ -4,12 +4,12 @@
// construct to `Option` that can be used to express error conditions. Change
// the function signature and body to return `Result<String, String>` instead
// of `Option<String>`.
-fn generate_nametag_text(name: String) -> Option<String> {
+fn generate_nametag_text(name: String) -> Result<String, String> {
if name.is_empty() {
// Empty names aren't allowed
- None
+ Err("Empty names aren't allowed".to_string())
} else {
- Some(format!("Hi! My name is {name}"))
+ Ok(format!("Hi! My name is {name}"))
}
}
Exercicse 49
diff --git a/exercises/13_error_handling/errors2.rs b/exercises/13_error_handling/errors2.rs
index defe359..3d850f7 100644
--- a/exercises/13_error_handling/errors2.rs
+++ b/exercises/13_error_handling/errors2.rs
@@ -21,7 +21,7 @@ fn total_cost(item_quantity: &str) -> Result<i32, ParseIntError> {
let cost_per_item = 5;
// TODO: Handle the error case as described above.
- let qty = item_quantity.parse::<i32>();
+ let qty = item_quantity.parse::<i32>()?;
Ok(qty * cost_per_item + processing_fee)
}
Exercicse 50
diff --git a/exercises/13_error_handling/errors3.rs b/exercises/13_error_handling/errors3.rs
index 8e8c38a..bf21bbc 100644
--- a/exercises/13_error_handling/errors3.rs
+++ b/exercises/13_error_handling/errors3.rs
@@ -15,7 +15,7 @@ fn total_cost(item_quantity: &str) -> Result<i32, ParseIntError> {
// TODO: Fix the compiler error by changing the signature and body of the
// `main` function.
-fn main() {
+fn main() -> Result<(), ParseIntError> {
let mut tokens = 100;
let pretend_user_input = "8";
@@ -28,4 +28,6 @@ fn main() {
tokens -= cost;
println!("You now have {tokens} tokens.");
}
+
+ Ok(())
}
Exercicse 51
diff --git a/exercises/13_error_handling/errors4.rs b/exercises/13_error_handling/errors4.rs
index 144fce7..9b8c550 100644
--- a/exercises/13_error_handling/errors4.rs
+++ b/exercises/13_error_handling/errors4.rs
@@ -11,7 +11,13 @@ impl PositiveNonzeroInteger {
fn new(value: i64) -> Result<Self, CreationError> {
// TODO: This function shouldn't always return an `Ok`.
// Read the tests below to clarify what should be returned.
- Ok(Self(value as u64))
+ if value < 0 {
+ Err(CreationError::Negative)
+ } else if value == 0 {
+ Err(CreationError::Zero)
+ } else {
+ Ok(PositiveNonzeroInteger(value as u64))
+ }
}
}
Exercicse 52
diff --git a/exercises/13_error_handling/errors5.rs b/exercises/13_error_handling/errors5.rs
index 125779b..df546f2 100644
--- a/exercises/13_error_handling/errors5.rs
+++ b/exercises/13_error_handling/errors5.rs
@@ -11,7 +11,7 @@
// context. For this exercise, that context is the potential errors which
// can be returned in a `Result`.
-use std::error::Error;
+use std::error::{self, Error};
use std::fmt;
#[derive(PartialEq, Debug)]
@@ -48,7 +48,7 @@ impl PositiveNonzeroInteger {
// TODO: Add the correct return type `Result<(), Box<dyn ???>>`. What can we
// use to describe both errors? Is there a trait which both errors implement?
-fn main() {
+fn main() -> Result<(), Box<dyn error::Error>> {
let pretend_user_input = "42";
let x: i64 = pretend_user_input.parse()?;
println!("output={:?}", PositiveNonzeroInteger::new(x)?);
Exercicse 53
diff --git a/exercises/13_error_handling/errors6.rs b/exercises/13_error_handling/errors6.rs
index b1995e0..353b50b 100644
--- a/exercises/13_error_handling/errors6.rs
+++ b/exercises/13_error_handling/errors6.rs
@@ -25,7 +25,9 @@ impl ParsePosNonzeroError {
}
// TODO: Add another error conversion function here.
- // fn from_parse_int(???) -> Self { ??? }
+ fn from_parse_int(err: ParseIntError) -> Self {
+ Self::ParseInt(err)
+ }
}
#[derive(PartialEq, Debug)]
@@ -43,7 +45,7 @@ impl PositiveNonzeroInteger {
fn parse(s: &str) -> Result<Self, ParsePosNonzeroError> {
// TODO: change this to return an appropriate error instead of panicking
// when `parse()` returns an error.
- let x: i64 = s.parse().unwrap();
+ let x: i64 = s.parse().map_err(ParsePosNonzeroError::from_parse_int)?;
Self::new(x).map_err(ParsePosNonzeroError::from_creation)
}
}
Exercicse 54
diff --git a/exercises/14_generics/generics1.rs b/exercises/14_generics/generics1.rs
index 87ed990..e13fd82 100644
--- a/exercises/14_generics/generics1.rs
+++ b/exercises/14_generics/generics1.rs
@@ -6,7 +6,7 @@ fn main() {
// TODO: Fix the compiler error by annotating the type of the vector
// `Vec<T>`. Choose `T` as some integer type that can be created from
// `u8` and `i8`.
- let mut numbers = Vec::new();
+ let mut numbers: Vec<i16> = Vec::new();
// Don't change the lines below.
let n1: u8 = 42;
Exercicse 55
diff --git a/exercises/14_generics/generics2.rs b/exercises/14_generics/generics2.rs
index 8908725..ba77625 100644
--- a/exercises/14_generics/generics2.rs
+++ b/exercises/14_generics/generics2.rs
@@ -1,12 +1,12 @@
// This powerful wrapper provides the ability to store a positive integer value.
// TODO: Rewrite it using a generic so that it supports wrapping ANY type.
-struct Wrapper {
- value: u32,
+struct Wrapper<T> {
+ value: T,
}
// TODO: Adapt the struct's implementation to be generic over the wrapped value.
-impl Wrapper {
- fn new(value: u32) -> Self {
+impl<T> Wrapper<T> {
+ fn new(value: T) -> Self {
Wrapper { value }
}
}
Exercicse 56
diff --git a/exercises/15_traits/traits1.rs b/exercises/15_traits/traits1.rs
index 85be17e..790873f 100644
--- a/exercises/15_traits/traits1.rs
+++ b/exercises/15_traits/traits1.rs
@@ -5,7 +5,9 @@ trait AppendBar {
}
impl AppendBar for String {
- // TODO: Implement `AppendBar` for the type `String`.
+ fn append_bar(self) -> Self {
+ self + "Bar"
+ }
}
fn main() {
Exercicse 57
diff --git a/exercises/15_traits/traits2.rs b/exercises/15_traits/traits2.rs
index d724dc2..2c110d7 100644
--- a/exercises/15_traits/traits2.rs
+++ b/exercises/15_traits/traits2.rs
@@ -4,6 +4,12 @@ trait AppendBar {
// TODO: Implement the trait `AppendBar` for a vector of strings.
// `append_bar` should push the string "Bar" into the vector.
+impl AppendBar for Vec<String> {
+ fn append_bar(mut self) -> Self {
+ self.push(String::from("Bar"));
+ self
+ }
+}
fn main() {
// You can optionally experiment here.
Exercicse 58
diff --git a/exercises/15_traits/traits3.rs b/exercises/15_traits/traits3.rs
index c244650..1294951 100644
--- a/exercises/15_traits/traits3.rs
+++ b/exercises/15_traits/traits3.rs
@@ -3,7 +3,9 @@ trait Licensed {
// implementors like the two structs below can share that default behavior
// without repeating the function.
// The default license information should be the string "Default license".
- fn licensing_info(&self) -> String;
+ fn licensing_info(&self) -> String {
+ "Default license".to_string()
+ }
}
struct SomeSoftware {
Exercicse 59
diff --git a/exercises/15_traits/traits4.rs b/exercises/15_traits/traits4.rs
index 80092a6..b23dcdd 100644
--- a/exercises/15_traits/traits4.rs
+++ b/exercises/15_traits/traits4.rs
@@ -11,7 +11,7 @@ impl Licensed for SomeSoftware {}
impl Licensed for OtherSoftware {}
// TODO: Fix the compiler error by only changing the signature of this function.
-fn compare_license_types(software1: ???, software2: ???) -> bool {
+fn compare_license_types(software1: impl Licensed, software2: impl Licensed) -> bool {
software1.licensing_info() == software2.licensing_info()
}
Exercicse 60
diff --git a/exercises/15_traits/traits5.rs b/exercises/15_traits/traits5.rs
index 5b356ac..3f48437 100644
--- a/exercises/15_traits/traits5.rs
+++ b/exercises/15_traits/traits5.rs
@@ -19,7 +19,7 @@ impl SomeTrait for OtherStruct {}
impl OtherTrait for OtherStruct {}
// TODO: Fix the compiler error by only changing the signature of this function.
-fn some_func(item: ???) -> bool {
+fn some_func(item: impl SomeTrait + OtherTrait) -> bool {
item.some_function() && item.other_function()
}
Exercicse 61
diff --git a/exercises/16_lifetimes/lifetimes1.rs b/exercises/16_lifetimes/lifetimes1.rs
index 19e2d39..b31845f 100644
--- a/exercises/16_lifetimes/lifetimes1.rs
+++ b/exercises/16_lifetimes/lifetimes1.rs
@@ -4,12 +4,8 @@
// not own their own data. What if their owner goes out of scope?
// TODO: Fix the compiler error by updating the function signature.
-fn longest(x: &str, y: &str) -> &str {
- if x.len() > y.len() {
- x
- } else {
- y
- }
+fn longest(x: &'static str, y: &'static str) -> &'static str {
+ if x.len() > y.len() { x } else { y }
}
fn main() {
Exercicse 62
diff --git a/exercises/16_lifetimes/lifetimes2.rs b/exercises/16_lifetimes/lifetimes2.rs
index de5a5df..b33a7c8 100644
--- a/exercises/16_lifetimes/lifetimes2.rs
+++ b/exercises/16_lifetimes/lifetimes2.rs
@@ -1,19 +1,15 @@
// Don't change this function.
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
- if x.len() > y.len() {
- x
- } else {
- y
- }
+ if x.len() > y.len() { x } else { y }
}
fn main() {
// TODO: Fix the compiler error by moving one line.
let string1 = String::from("long string is long");
+ let string2 = String::from("xyz");
let result;
{
- let string2 = String::from("xyz");
result = longest(&string1, &string2);
}
println!("The longest string is '{result}'");
Exercicse 63
diff --git a/exercises/16_lifetimes/lifetimes3.rs b/exercises/16_lifetimes/lifetimes3.rs
index 1cc2759..53165ff 100644
--- a/exercises/16_lifetimes/lifetimes3.rs
+++ b/exercises/16_lifetimes/lifetimes3.rs
@@ -2,8 +2,8 @@
// TODO: Fix the compiler errors about the struct.
struct Book {
- author: &str,
- title: &str,
+ author: &'static str,
+ title: &'static str,
}
fn main() {
Exercicse 64
diff --git a/exercises/17_tests/tests1.rs b/exercises/17_tests/tests1.rs
index 7529f9f..774d77a 100644
--- a/exercises/17_tests/tests1.rs
+++ b/exercises/17_tests/tests1.rs
@@ -14,10 +14,13 @@ mod tests {
// TODO: Import `is_even`. You can use a wildcard to import everything in
// the outer module.
+ use crate::is_even;
+
#[test]
fn you_can_assert() {
// TODO: Test the function `is_even` with some values.
- assert!();
- assert!();
+ assert!(is_even(4));
+ assert!(is_even(8));
+ assert!(!is_even(7));
}
}
Exercicse 65
diff --git a/exercises/17_tests/tests2.rs b/exercises/17_tests/tests2.rs
index 0c6573e..485b7c8 100644
--- a/exercises/17_tests/tests2.rs
+++ b/exercises/17_tests/tests2.rs
@@ -15,9 +15,9 @@ mod tests {
#[test]
fn you_can_assert_eq() {
// TODO: Test the function `power_of_2` with some values.
- assert_eq!();
- assert_eq!();
- assert_eq!();
- assert_eq!();
+ assert_eq!(power_of_2(4), 16);
+ assert_eq!(power_of_2(10), 1024);
+ assert_eq!(power_of_2(16), 65536);
+ assert_eq!(power_of_2(32), 4294967296);
}
}
Exercicse 66
diff --git a/exercises/17_tests/tests3.rs b/exercises/17_tests/tests3.rs
index 822184e..085bb62 100644
--- a/exercises/17_tests/tests3.rs
+++ b/exercises/17_tests/tests3.rs
@@ -29,13 +29,14 @@ mod tests {
// TODO: This test should check if the rectangle has the size that we
// pass to its constructor.
let rect = Rectangle::new(10, 20);
- assert_eq!(todo!(), 10); // Check width
- assert_eq!(todo!(), 20); // Check height
+ assert_eq!(rect.width, 10); // Check width
+ assert_eq!(rect.height, 20); // Check height
}
// TODO: This test should check if the program panics when we try to create
// a rectangle with negative width.
#[test]
+ #[should_panic]
fn negative_width() {
let _rect = Rectangle::new(-10, 10);
}
@@ -43,6 +44,7 @@ mod tests {
// TODO: This test should check if the program panics when we try to create
// a rectangle with negative height.
#[test]
+ #[should_panic]
fn negative_height() {
let _rect = Rectangle::new(10, -10);
}
diff --git a/exercises/19_smart_pointers/arc1.rs b/exercises/19_smart_pointers/arc1.rs
index 6bb860f..a5b9467 100644
--- a/exercises/19_smart_pointers/arc1.rs
+++ b/exercises/19_smart_pointers/arc1.rs
@@ -23,13 +23,13 @@ fn main() {
let numbers: Vec<_> = (0..100u32).collect();
// TODO: Define `shared_numbers` by using `Arc`.
- // let shared_numbers = ???;
+ let shared_numbers = Arc::new(numbers);
let mut join_handles = Vec::new();
for offset in 0..8 {
// TODO: Define `child_numbers` using `shared_numbers`.
- // let child_numbers = ???;
+ let child_numbers = Arc::clone(&shared_numbers);
let handle = thread::spawn(move || {
let sum: u32 = child_numbers.iter().filter(|&&n| n % 8 == offset).sum();
Exercicse 73
diff --git a/exercises/19_smart_pointers/box1.rs b/exercises/19_smart_pointers/box1.rs
index d70e1c3..483e5f6 100644
--- a/exercises/19_smart_pointers/box1.rs
+++ b/exercises/19_smart_pointers/box1.rs
@@ -12,18 +12,18 @@
// TODO: Use a `Box` in the enum definition to make the code compile.
#[derive(PartialEq, Debug)]
enum List {
- Cons(i32, List),
+ Cons(i32, Box<List>),
Nil,
}
// TODO: Create an empty cons list.
fn create_empty_list() -> List {
- todo!()
+ List::Nil
}
// TODO: Create a non-empty cons list.
fn create_non_empty_list() -> List {
- todo!()
+ List::Cons(42, Box::new(List::Nil))
}
fn main() {
Exercicse 74
diff --git a/exercises/19_smart_pointers/cow1.rs b/exercises/19_smart_pointers/cow1.rs
index 1566500..0c9c1d6 100644
--- a/exercises/19_smart_pointers/cow1.rs
+++ b/exercises/19_smart_pointers/cow1.rs
@@ -39,7 +39,7 @@ mod tests {
let mut input = Cow::from(&vec);
abs_all(&mut input);
// TODO: Replace `todo!()` with `Cow::Owned(_)` or `Cow::Borrowed(_)`.
- assert!(matches!(input, todo!()));
+ assert!(matches!(input, Cow::Borrowed(_)));
}
#[test]
@@ -52,7 +52,7 @@ mod tests {
let mut input = Cow::from(vec);
abs_all(&mut input);
// TODO: Replace `todo!()` with `Cow::Owned(_)` or `Cow::Borrowed(_)`.
- assert!(matches!(input, todo!()));
+ assert!(matches!(input, Cow::Owned(_)));
}
#[test]
@@ -64,6 +64,6 @@ mod tests {
let mut input = Cow::from(vec);
abs_all(&mut input);
// TODO: Replace `todo!()` with `Cow::Owned(_)` or `Cow::Borrowed(_)`.
- assert!(matches!(input, todo!()));
+ assert!(matches!(input, Cow::Owned(_)));
}
}
Exercicse 75
diff --git a/exercises/19_smart_pointers/rc1.rs b/exercises/19_smart_pointers/rc1.rs
index ecd3438..5c9ce84 100644
--- a/exercises/19_smart_pointers/rc1.rs
+++ b/exercises/19_smart_pointers/rc1.rs
@@ -60,17 +60,17 @@ mod tests {
jupiter.details();
// TODO
- let saturn = Planet::Saturn(Rc::new(Sun));
+ let saturn = Planet::Saturn(Rc::clone(&sun));
println!("reference count = {}", Rc::strong_count(&sun)); // 7 references
saturn.details();
// TODO
- let uranus = Planet::Uranus(Rc::new(Sun));
+ let uranus = Planet::Uranus(Rc::clone(&sun));
println!("reference count = {}", Rc::strong_count(&sun)); // 8 references
uranus.details();
// TODO
- let neptune = Planet::Neptune(Rc::new(Sun));
+ let neptune = Planet::Neptune(Rc::clone(&sun));
println!("reference count = {}", Rc::strong_count(&sun)); // 9 references
neptune.details();
@@ -92,12 +92,15 @@ mod tests {
println!("reference count = {}", Rc::strong_count(&sun)); // 4 references
// TODO
+ drop(earth);
println!("reference count = {}", Rc::strong_count(&sun)); // 3 references
// TODO
+ drop(venus);
println!("reference count = {}", Rc::strong_count(&sun)); // 2 references
// TODO
+ drop(mercury);
println!("reference count = {}", Rc::strong_count(&sun)); // 1 reference
assert_eq!(Rc::strong_count(&sun), 1);
Exercicse 76
diff --git a/exercises/20_threads/threads1.rs b/exercises/20_threads/threads1.rs
index dbc64b1..84f094c 100644
--- a/exercises/20_threads/threads1.rs
+++ b/exercises/20_threads/threads1.rs
@@ -24,6 +24,7 @@ fn main() {
for handle in handles {
// TODO: Collect the results of all threads into the `results` vector.
// Use the `JoinHandle` struct which is returned by `thread::spawn`.
+ results.push(handle.join().unwrap());
}
if results.len() != 10 {
Exercicse 77
diff --git a/exercises/20_threads/threads2.rs b/exercises/20_threads/threads2.rs
index 7020cb9..e599d2b 100644
--- a/exercises/20_threads/threads2.rs
+++ b/exercises/20_threads/threads2.rs
@@ -2,7 +2,11 @@
// work. But this time, the spawned threads need to be in charge of updating a
// shared value: `JobStatus.jobs_done`
-use std::{sync::Arc, thread, time::Duration};
+use std::{
+ sync::{Arc, Mutex},
+ thread,
+ time::Duration,
+};
struct JobStatus {
jobs_done: u32,
@@ -10,7 +14,7 @@ struct JobStatus {
fn main() {
// TODO: `Arc` isn't enough if you want a **mutable** shared state.
- let status = Arc::new(JobStatus { jobs_done: 0 });
+ let status = Arc::new(Mutex::new(JobStatus { jobs_done: 0 }));
let mut handles = Vec::new();
for _ in 0..10 {
@@ -19,7 +23,7 @@ fn main() {
thread::sleep(Duration::from_millis(250));
// TODO: You must take an action before you update a shared value.
- status_shared.jobs_done += 1;
+ status_shared.lock().unwrap().jobs_done += 1;
});
handles.push(handle);
}
@@ -30,5 +34,5 @@ fn main() {
}
// TODO: Print the value of `JobStatus.jobs_done`.
- println!("Jobs done: {}", todo!());
+ println!("Jobs done: {}", status.lock().unwrap().jobs_done);
}
Exercicse 78
diff --git a/exercises/20_threads/threads3.rs b/exercises/20_threads/threads3.rs
index 6d16bd9..af85fd5 100644
--- a/exercises/20_threads/threads3.rs
+++ b/exercises/20_threads/threads3.rs
@@ -17,10 +17,11 @@ impl Queue {
fn send_tx(q: Queue, tx: mpsc::Sender<u32>) {
// TODO: We want to send `tx` to both threads. But currently, it is moved
// into the first thread. How could you solve this problem?
+ let tx_clone = tx.clone();
thread::spawn(move || {
for val in q.first_half {
println!("Sending {val:?}");
- tx.send(val).unwrap();
+ tx_clone.send(val).unwrap();
thread::sleep(Duration::from_millis(250));
}
});
diff --git a/exercises/21_macros/macros2.rs b/exercises/21_macros/macros2.rs
index 2d9dec7..f310a0b 100644
--- a/exercises/21_macros/macros2.rs
+++ b/exercises/21_macros/macros2.rs
@@ -1,10 +1,10 @@
-fn main() {
- my_macro!();
-}
-
// TODO: Fix the compiler error by moving the whole definition of this macro.
macro_rules! my_macro {
() => {
println!("Check out my macro!");
};
}
+
+fn main() {
+ my_macro!();
+}
Exercicse 81
diff --git a/exercises/21_macros/macros3.rs b/exercises/21_macros/macros3.rs
index 9537494..acda10b 100644
--- a/exercises/21_macros/macros3.rs
+++ b/exercises/21_macros/macros3.rs
@@ -1,5 +1,6 @@
// TODO: Fix the compiler error without taking the macro definition out of this
// module.
+#[macro_use]
mod macros {
macro_rules! my_macro {
() => {
Exercicse 82
diff --git a/exercises/21_macros/macros4.rs b/exercises/21_macros/macros4.rs
index 9d77f6a..3396f0d 100644
--- a/exercises/21_macros/macros4.rs
+++ b/exercises/21_macros/macros4.rs
@@ -3,7 +3,7 @@
macro_rules! my_macro {
() => {
println!("Check out my macro!");
- }
+ };
($val:expr) => {
println!("Look at this other macro: {}", $val);
}
Exercicse 83
diff --git a/exercises/22_clippy/clippy1.rs b/exercises/22_clippy/clippy1.rs
index 7165da4..0c5e9f2 100644
--- a/exercises/22_clippy/clippy1.rs
+++ b/exercises/22_clippy/clippy1.rs
@@ -4,9 +4,11 @@
// For these exercises, the code will fail to compile when there are Clippy
// warnings. Check Clippy's suggestions from the output to solve the exercise.
+use std::f32::consts::PI;
+
fn main() {
// TODO: Fix the Clippy lint in this line.
- let pi = 3.14;
+ let pi = PI;
let radius: f32 = 5.0;
let area = pi * radius.powi(2);
Exercicse 84
diff --git a/exercises/22_clippy/clippy2.rs b/exercises/22_clippy/clippy2.rs
index 8cfe6f8..c0533ed 100644
--- a/exercises/22_clippy/clippy2.rs
+++ b/exercises/22_clippy/clippy2.rs
@@ -2,7 +2,7 @@ fn main() {
let mut res = 42;
let option = Some(12);
// TODO: Fix the Clippy lint.
- for x in option {
+ if let Some(x) = option {
res += x;
}
Exercicse 85
diff --git a/exercises/22_clippy/clippy3.rs b/exercises/22_clippy/clippy3.rs
index 7a3cb39..0a6b1f0 100644
--- a/exercises/22_clippy/clippy3.rs
+++ b/exercises/22_clippy/clippy3.rs
@@ -1,5 +1,6 @@
// Here are some more easy Clippy fixes so you can see its utility 📎
// TODO: Fix all the Clippy lints.
+use std::mem;
#[rustfmt::skip]
#[allow(unused_variables, unused_assignments)]
@@ -7,23 +8,23 @@ fn main() {
let my_option: Option<&str> = None;
// Assume that you don't know the value of `my_option`.
// In the case of `Some`, we want to print its value.
- if my_option.is_none() {
- println!("{}", my_option.unwrap());
+ if let Some(value) = my_option {
+ println!("{value}");
}
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;
+ mem::swap(&mut value_a, &mut value_b);
println!("value a: {value_a}; value b: {value_b}");
}
Exercicse 86
diff --git a/exercises/23_conversions/as_ref_mut.rs b/exercises/23_conversions/as_ref_mut.rs
index d7892dd..cc85a78 100644
--- a/exercises/23_conversions/as_ref_mut.rs
+++ b/exercises/23_conversions/as_ref_mut.rs
@@ -5,20 +5,21 @@
// Obtain the number of bytes (not characters) in the given argument
// (`.len()` returns the number of bytes in a string).
// TODO: 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().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 {
+fn char_counter<T: AsRef<str>>(arg: T) -> usize {
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.
+fn num_sq<T: AsMut<u32>>(arg: &mut T) {
+ let arg = arg.as_mut();
+ *arg *= *arg;
}
fn main() {
Exercicse 87
diff --git a/exercises/23_conversions/from_into.rs b/exercises/23_conversions/from_into.rs
index bc2783a..f586676 100644
--- a/exercises/23_conversions/from_into.rs
+++ b/exercises/23_conversions/from_into.rs
@@ -34,7 +34,35 @@ impl Default for Person {
// 5. Parse the second element from the split operation into a `u8` as the age.
// 6. If parsing the age fails, return the default of `Person`.
impl From<&str> for Person {
- fn from(s: &str) -> Self {}
+ fn from(s: &str) -> Person {
+ if s.is_empty() {
+ Person::default()
+ } else {
+ s.split(",")
+ .map(|x| x.into())
+ .collect::<Vec<String>>()
+ .into()
+ }
+ }
+}
+
+impl From<Vec<String>> for Person {
+ fn from(s: Vec<String>) -> Self {
+ if s.len() < 2 {
+ return Person::default();
+ }
+ let number = s[1].parse();
+ let age;
+ if number.is_err() || s[0].is_empty() {
+ Person::default()
+ } else {
+ age = number.unwrap();
+ Person {
+ name: s[0].clone(),
+ age,
+ }
+ }
+ }
}
fn main() {
@@ -117,14 +145,14 @@ mod tests {
#[test]
fn test_trailing_comma() {
let p: Person = Person::from("Mike,32,");
- assert_eq!(p.name, "John");
- assert_eq!(p.age, 30);
+ assert_eq!(p.name, "Mike");
+ assert_eq!(p.age, 32);
}
#[test]
fn test_trailing_comma_and_some_string() {
let p: Person = Person::from("Mike,32,dog");
- assert_eq!(p.name, "John");
- assert_eq!(p.age, 30);
+ assert_eq!(p.name, "Mike");
+ assert_eq!(p.age, 32);
}
}
Exercicse 88
diff --git a/exercises/23_conversions/from_str.rs b/exercises/23_conversions/from_str.rs
index ec6d3fd..8556380 100644
--- a/exercises/23_conversions/from_str.rs
+++ b/exercises/23_conversions/from_str.rs
@@ -8,6 +8,8 @@
use std::num::ParseIntError;
use std::str::FromStr;
+use crate::ParsePersonError::ParseInt;
+
#[derive(Debug, PartialEq)]
struct Person {
name: String,
@@ -41,7 +43,23 @@ enum ParsePersonError {
impl FromStr for Person {
type Err = ParsePersonError;
- fn from_str(s: &str) -> Result<Self, Self::Err> {}
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
+ let mut split = s.split(',');
+ let (Some(name), Some(age), None) = (split.next(), split.next(), split.next()) else {
+ return Err(ParsePersonError::BadLen);
+ };
+
+ if name.is_empty() {
+ return Err(ParsePersonError::NoName);
+ }
+
+ let age = age.parse().map_err(ParseInt)?;
+
+ Ok(Self {
+ name: name.into(),
+ age,
+ })
+ }
}
fn main() {
Exercicse 89
diff --git a/exercises/23_conversions/try_from_into.rs b/exercises/23_conversions/try_from_into.rs
index f3ae80a..5929a02 100644
--- a/exercises/23_conversions/try_from_into.rs
+++ b/exercises/23_conversions/try_from_into.rs
@@ -28,14 +28,27 @@ enum IntoColorError {
impl TryFrom<(i16, i16, i16)> for Color {
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> {
+ for i in [tuple.0, tuple.1, tuple.2] {
+ if !(0..=255).contains(&i) {
+ return Err(IntoColorError::IntConversion);
+ }
+ }
+ Ok(Color {
+ red: tuple.0 as u8,
+ green: tuple.1 as u8,
+ blue: tuple.2 as u8,
+ })
+ }
}
// TODO: Array implementation.
impl TryFrom<[i16; 3]> for Color {
type Error = IntoColorError;
- fn try_from(arr: [i16; 3]) -> Result<Self, Self::Error> {}
+ fn try_from(arr: [i16; 3]) -> Result<Self, Self::Error> {
+ Color::try_from((arr[0], arr[1], arr[2]))
+ }
}
// TODO: Slice implementation.
@@ -43,7 +56,13 @@ impl TryFrom<[i16; 3]> for Color {
impl TryFrom<&[i16]> for Color {
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 {
+ Err(IntoColorError::BadLen)
+ } else {
+ Color::try_from((slice[0], slice[1], slice[2]))
+ }
+ }
}
fn main() {
Exercicse 90
diff --git a/exercises/23_conversions/using_as.rs b/exercises/23_conversions/using_as.rs
index c131d1f..dff453b 100644
--- a/exercises/23_conversions/using_as.rs
+++ b/exercises/23_conversions/using_as.rs
@@ -5,7 +5,7 @@
fn average(values: &[f64]) -> f64 {
let total = values.iter().sum::<f64>();
// TODO: Make a conversion before dividing.
- total / values.len()
+ total / values.len() as f64
}
fn main() {
Exercicse 91
diff --git a/exercises/quizzes/quiz1.rs b/exercises/quizzes/quiz1.rs
index 04fb2aa..bd974d6 100644
--- a/exercises/quizzes/quiz1.rs
+++ b/exercises/quizzes/quiz1.rs
@@ -10,7 +10,9 @@
// TODO: Write a function that calculates the price of an order of apples given
// the quantity bought.
-// fn calculate_price_of_apples(???) -> ??? { ??? }
+fn calculate_price_of_apples(num: i32) -> i32 {
+ if num > 40 { num } else { num * 2 }
+}
fn main() {
// You can optionally experiment here.
Exercicse 92
diff --git a/exercises/quizzes/quiz2.rs b/exercises/quizzes/quiz2.rs
index 2cddba9..415d8e3 100644
--- a/exercises/quizzes/quiz2.rs
+++ b/exercises/quizzes/quiz2.rs
@@ -27,7 +27,17 @@ mod my_module {
use super::Command;
// TODO: Complete the function as described above.
- // pub fn transformer(input: ???) -> ??? { ??? }
+ pub fn transformer(input: Vec<(String, Command)>) -> Vec<String> {
+ let mut transform: Vec<String> = vec![];
+ for x in input.iter() {
+ match x.1 {
+ Command::Uppercase => transform.push(x.0.to_uppercase()),
+ Command::Trim => transform.push(String::from(x.0.trim())),
+ Command::Append(c) => transform.push(x.0.clone() + &"bar".repeat(c)),
+ }
+ }
+ transform
+ }
}
fn main() {
@@ -37,8 +47,8 @@ fn main() {
#[cfg(test)]
mod tests {
// TODO: What do we need to import to have `transformer` in scope?
- // use ???;
use super::Command;
+ use crate::my_module::transformer;
#[test]
fn it_works() {
Exercicse 93
diff --git a/exercises/quizzes/quiz3.rs b/exercises/quizzes/quiz3.rs
index c877c5f..fdd4735 100644
--- a/exercises/quizzes/quiz3.rs
+++ b/exercises/quizzes/quiz3.rs
@@ -12,14 +12,16 @@
// block to support alphabetical report cards in addition to numerical ones.
// TODO: Adjust the struct as described above.
-struct ReportCard {
- grade: f32,
+struct ReportCard<T> {
+ grade: T,
student_name: String,
student_age: u8,
}
+use std::fmt::Display;
+
// TODO: Adjust the impl block as described above.
-impl ReportCard {
+impl<T: Display> ReportCard<T> {
fn print(&self) -> String {
format!(
"{} ({}) - achieved a grade of {}",