Clean up and unify exercises

pull/1949/head
mo8it 5 months ago
parent cb9f1ac9ce
commit 2f810a4da6

@ -1,5 +1,3 @@
// intro1.rs
//
// We sometimes encourage you to keep trying things on a given exercise, even // We sometimes encourage you to keep trying things on a given exercise, even
// after you already figured it out. If you got everything working and feel // after you already figured it out. If you got everything working and feel
// ready for the next exercise, remove the `I AM NOT DONE` comment below. // ready for the next exercise, remove the `I AM NOT DONE` comment below.
@ -8,9 +6,6 @@
// reloaded when you change one of the lines below! Try adding a `println!` // reloaded when you change one of the lines below! Try adding a `println!`
// line, or try changing what it outputs in your terminal. Try removing a // line, or try changing what it outputs in your terminal. Try removing a
// semicolon and see what happens! // semicolon and see what happens!
//
// Execute `rustlings hint intro1` or use the `hint` watch subcommand for a
// hint.
fn main() { fn main() {
println!("Hello and"); println!("Hello and");

@ -1,9 +1,4 @@
// intro2.rs
//
// Make the code print a greeting to the world. // Make the code print a greeting to the world.
//
// Execute `rustlings hint intro2` or use the `hint` watch subcommand for a
// hint.
fn main() { fn main() {
printline!("Hello there!") printline!("Hello there!")

@ -1,9 +1,4 @@
// variables1.rs
//
// Make me compile! // Make me compile!
//
// Execute `rustlings hint variables1` or use the `hint` watch subcommand for a
// hint.
fn main() { fn main() {
x = 5; x = 5;

@ -1,8 +1,3 @@
// variables2.rs
//
// Execute `rustlings hint variables2` or use the `hint` watch subcommand for a
// hint.
fn main() { fn main() {
let x; let x;
if x == 10 { if x == 10 {

@ -1,8 +1,3 @@
// variables3.rs
//
// Execute `rustlings hint variables3` or use the `hint` watch subcommand for a
// hint.
fn main() { fn main() {
let x: i32; let x: i32;
println!("Number {}", x); println!("Number {}", x);

@ -1,8 +1,3 @@
// variables4.rs
//
// Execute `rustlings hint variables4` or use the `hint` watch subcommand for a
// hint.
fn main() { fn main() {
let x = 3; let x = 3;
println!("Number {}", x); println!("Number {}", x);

@ -1,8 +1,3 @@
// variables5.rs
//
// Execute `rustlings hint variables5` or use the `hint` watch subcommand for a
// hint.
fn main() { fn main() {
let number = "T-H-R-E-E"; // don't change this line let number = "T-H-R-E-E"; // don't change this line
println!("Spell a Number : {}", number); println!("Spell a Number : {}", number);

@ -1,8 +1,3 @@
// variables6.rs
//
// Execute `rustlings hint variables6` or use the `hint` watch subcommand for a
// hint.
const NUMBER = 3; const NUMBER = 3;
fn main() { fn main() {
println!("Number {}", NUMBER); println!("Number {}", NUMBER);

@ -1,8 +1,3 @@
// functions1.rs
//
// Execute `rustlings hint functions1` or use the `hint` watch subcommand for a
// hint.
fn main() { fn main() {
call_me(); call_me();
} }

@ -1,8 +1,3 @@
// functions2.rs
//
// Execute `rustlings hint functions2` or use the `hint` watch subcommand for a
// hint.
fn main() { fn main() {
call_me(3); call_me(3);
} }

@ -1,8 +1,3 @@
// functions3.rs
//
// Execute `rustlings hint functions3` or use the `hint` watch subcommand for a
// hint.
fn main() { fn main() {
call_me(); call_me();
} }

@ -1,12 +1,7 @@
// functions4.rs
//
// This store is having a sale where if the price is an even number, you get 10 // This store is having a sale where if the price is an even number, you get 10
// Rustbucks off, but if it's an odd number, it's 3 Rustbucks off. (Don't worry // Rustbucks off, but if it's an odd number, it's 3 Rustbucks off. (Don't worry
// about the function bodies themselves, we're only interested in the signatures // about the function bodies themselves, we're only interested in the signatures
// for now. If anything, this is a good way to peek ahead to future exercises!) // for now. If anything, this is a good way to peek ahead to future exercises!)
//
// Execute `rustlings hint functions4` or use the `hint` watch subcommand for a
// hint.
fn main() { fn main() {
let original_price = 51; let original_price = 51;

@ -1,8 +1,3 @@
// functions5.rs
//
// Execute `rustlings hint functions5` or use the `hint` watch subcommand for a
// hint.
fn main() { fn main() {
let answer = square(3); let answer = square(3);
println!("The square of 3 is {}", answer); println!("The square of 3 is {}", answer);

@ -1,7 +1,3 @@
// if1.rs
//
// Execute `rustlings hint if1` or use the `hint` watch subcommand for a hint.
pub fn bigger(a: i32, b: i32) -> i32 { pub fn bigger(a: i32, b: i32) -> i32 {
// Complete this function to return the bigger number! // Complete this function to return the bigger number!
// If both numbers are equal, any of them can be returned. // If both numbers are equal, any of them can be returned.

@ -1,9 +1,5 @@
// if2.rs
//
// Step 1: Make me compile! // Step 1: Make me compile!
// Step 2: Get the bar_for_fuzz and default_to_baz tests passing! // Step 2: Get the bar_for_fuzz and default_to_baz tests passing!
//
// Execute `rustlings hint if2` or use the `hint` watch subcommand for a hint.
pub fn foo_if_fizz(fizzish: &str) -> &str { pub fn foo_if_fizz(fizzish: &str) -> &str {
if fizzish == "fizz" { if fizzish == "fizz" {

@ -1,7 +1,3 @@
// if3.rs
//
// Execute `rustlings hint if3` or use the `hint` watch subcommand for a hint.
pub fn animal_habitat(animal: &str) -> &'static str { pub fn animal_habitat(animal: &str) -> &'static str {
let identifier = if animal == "crab" { let identifier = if animal == "crab" {
1 1

@ -1,7 +1,4 @@
// primitive_types1.rs // Fill in the rest of the line that has code missing!
//
// Fill in the rest of the line that has code missing! No hints, there's no
// tricks, just get used to typing these :)
fn main() { fn main() {
// Booleans (`bool`) // Booleans (`bool`)

@ -1,8 +1,3 @@
// primitive_types2.rs
//
// Fill in the rest of the line that has code missing! No hints, there's no
// tricks, just get used to typing these :)
fn main() { fn main() {
// Characters (`char`) // Characters (`char`)

@ -1,9 +1,4 @@
// primitive_types3.rs
//
// Create an array with at least 100 elements in it where the ??? is. // Create an array with at least 100 elements in it where the ??? is.
//
// Execute `rustlings hint primitive_types3` or use the `hint` watch subcommand
// for a hint.
fn main() { fn main() {
let a = ??? let a = ???

@ -1,19 +1,19 @@
// primitive_types4.rs
//
// Get a slice out of Array a where the ??? is so that the test passes. // Get a slice out of Array a where the ??? is so that the test passes.
//
// Execute `rustlings hint primitive_types4` or use the `hint` watch subcommand
// for a hint.
fn main() { fn main() {
// You can optionally experiment here. // You can optionally experiment here.
} }
#[test] #[cfg(test)]
fn slice_out_of_array() { mod tests {
let a = [1, 2, 3, 4, 5]; use super::*;
let nice_slice = ??? #[test]
fn slice_out_of_array() {
let a = [1, 2, 3, 4, 5];
assert_eq!([2, 3, 4], nice_slice) let nice_slice = ???
assert_eq!([2, 3, 4], nice_slice)
}
} }

@ -1,9 +1,4 @@
// primitive_types5.rs
//
// Destructure the `cat` tuple so that the println will work. // Destructure the `cat` tuple so that the println will work.
//
// Execute `rustlings hint primitive_types5` or use the `hint` watch subcommand
// for a hint.
fn main() { fn main() {
let cat = ("Furry McFurson", 3.5); let cat = ("Furry McFurson", 3.5);

@ -1,21 +1,21 @@
// primitive_types6.rs
//
// Use a tuple index to access the second element of `numbers`. You can put the // Use a tuple index to access the second element of `numbers`. You can put the
// expression for the second element where ??? is so that the test passes. // expression for the second element where ??? is so that the test passes.
//
// Execute `rustlings hint primitive_types6` or use the `hint` watch subcommand
// for a hint.
fn main() { fn main() {
// You can optionally experiment here. // You can optionally experiment here.
} }
#[test] #[cfg(test)]
fn indexing_tuple() { mod tests {
let numbers = (1, 2, 3); use super::*;
// Replace below ??? with the tuple indexing syntax.
let second = ???;
assert_eq!(2, second, #[test]
"This is not the 2nd number in the tuple!") fn indexing_tuple() {
let numbers = (1, 2, 3);
// Replace below ??? with the tuple indexing syntax.
let second = ???;
assert_eq!(2, second,
"This is not the 2nd number in the tuple!")
}
} }

@ -1,11 +1,7 @@
// vecs1.rs
//
// Your task is to create a `Vec` which holds the exact same elements as in the // Your task is to create a `Vec` which holds the exact same elements as in the
// array `a`. // array `a`.
// //
// Make me compile and pass the test! // Make me compile and pass the test!
//
// Execute `rustlings hint vecs1` or use the `hint` watch subcommand for a hint.
fn array_and_vec() -> ([i32; 4], Vec<i32>) { fn array_and_vec() -> ([i32; 4], Vec<i32>) {
let a = [10, 20, 30, 40]; // a plain array let a = [10, 20, 30, 40]; // a plain array

@ -1,11 +1,7 @@
// vecs2.rs
//
// A Vec of even numbers is given. Your task is to complete the loop so that // A Vec of even numbers is given. Your task is to complete the loop so that
// each number in the Vec is multiplied by 2. // each number in the Vec is multiplied by 2.
// //
// Make me pass the test! // Make me pass the test!
//
// Execute `rustlings hint vecs2` or use the `hint` watch subcommand for a hint.
fn vec_loop(mut v: Vec<i32>) -> Vec<i32> { fn vec_loop(mut v: Vec<i32>) -> Vec<i32> {
for element in v.iter_mut() { for element in v.iter_mut() {

@ -1,21 +1,25 @@
// move_semantics1.rs fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
// let vec = vec;
// Execute `rustlings hint move_semantics1` or use the `hint` watch subcommand
// for a hint.
#[test] vec.push(88);
fn main() {
let vec0 = vec![22, 44, 66];
let vec1 = fill_vec(vec0); vec
}
assert_eq!(vec1, vec![22, 44, 66, 88]); fn main() {
// You can optionally experiment here.
} }
fn fill_vec(vec: Vec<i32>) -> Vec<i32> { #[cfg(test)]
let vec = vec; mod tests {
use super::*;
vec.push(88); #[test]
fn move_semantics1() {
let vec0 = vec![22, 44, 66];
vec let vec1 = fill_vec(vec0);
assert_eq!(vec1, vec![22, 44, 66, 88]);
}
} }

@ -1,19 +1,4 @@
// move_semantics2.rs
//
// Make the test pass by finding a way to keep both Vecs separate! // Make the test pass by finding a way to keep both Vecs separate!
//
// Execute `rustlings hint move_semantics2` or use the `hint` watch subcommand
// for a hint.
#[test]
fn main() {
let vec0 = vec![22, 44, 66];
let vec1 = fill_vec(vec0);
assert_eq!(vec0, vec![22, 44, 66]);
assert_eq!(vec1, vec![22, 44, 66, 88]);
}
fn fill_vec(vec: Vec<i32>) -> Vec<i32> { fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
let mut vec = vec; let mut vec = vec;
@ -22,3 +7,22 @@ fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
vec vec
} }
fn main() {
// You can optionally experiment here.
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn move_semantics2() {
let vec0 = vec![22, 44, 66];
let vec1 = fill_vec(vec0);
assert_eq!(vec0, vec![22, 44, 66]);
assert_eq!(vec1, vec![22, 44, 66, 88]);
}
}

@ -1,22 +1,26 @@
// move_semantics3.rs
//
// Make me compile without adding new lines -- just changing existing lines! (no // Make me compile without adding new lines -- just changing existing lines! (no
// lines with multiple semicolons necessary!) // lines with multiple semicolons necessary!)
//
// Execute `rustlings hint move_semantics3` or use the `hint` watch subcommand
// for a hint.
#[test] fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
fn main() { vec.push(88);
let vec0 = vec![22, 44, 66];
let vec1 = fill_vec(vec0); vec
}
assert_eq!(vec1, vec![22, 44, 66, 88]); fn main() {
// You can optionally experiment here.
} }
fn fill_vec(vec: Vec<i32>) -> Vec<i32> { #[cfg(test)]
vec.push(88); mod tests {
use super::*;
vec #[test]
fn move_semantics3() {
let vec0 = vec![22, 44, 66];
let vec1 = fill_vec(vec0);
assert_eq!(vec1, vec![22, 44, 66, 88]);
}
} }

@ -1,20 +1,6 @@
// move_semantics4.rs
//
// Refactor this code so that instead of passing `vec0` into the `fill_vec` // Refactor this code so that instead of passing `vec0` into the `fill_vec`
// function, the Vector gets created in the function itself and passed back to // function, the Vector gets created in the function itself and passed back to
// the main function. // the test function.
//
// Execute `rustlings hint move_semantics4` or use the `hint` watch subcommand
// for a hint.
#[test]
fn main() {
let vec0 = vec![22, 44, 66];
let vec1 = fill_vec(vec0);
assert_eq!(vec1, vec![22, 44, 66, 88]);
}
// `fill_vec()` no longer takes `vec: Vec<i32>` as argument - don't change this! // `fill_vec()` no longer takes `vec: Vec<i32>` as argument - don't change this!
fn fill_vec() -> Vec<i32> { fn fill_vec() -> Vec<i32> {
@ -25,3 +11,21 @@ fn fill_vec() -> Vec<i32> {
vec vec
} }
fn main() {
// You can optionally experiment here.
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn move_semantics4() {
let vec0 = vec![22, 44, 66];
let vec1 = fill_vec(vec0);
assert_eq!(vec1, vec![22, 44, 66, 88]);
}
}

@ -1,17 +1,21 @@
// move_semantics5.rs // Make me compile only by reordering the lines in the test, but without adding,
//
// Make me compile only by reordering the lines in `main()`, but without adding,
// changing or removing any of them. // changing or removing any of them.
//
// Execute `rustlings hint move_semantics5` or use the `hint` watch subcommand
// for a hint.
#[test]
fn main() { fn main() {
let mut x = 100; // You can optionally experiment here.
let y = &mut x; }
let z = &mut x;
*y += 100; #[cfg(test)]
*z += 1000; mod tests {
assert_eq!(x, 1200); use super::*;
#[test]
fn move_semantics5() {
let mut x = 100;
let y = &mut x;
let z = &mut x;
*y += 100;
*z += 1000;
assert_eq!(x, 1200);
}
} }

@ -1,9 +1,4 @@
// move_semantics6.rs
//
// You can't change anything except adding or removing references. // You can't change anything except adding or removing references.
//
// Execute `rustlings hint move_semantics6` or use the `hint` watch subcommand
// for a hint.
fn main() { fn main() {
let data = "Rust is great!".to_string(); let data = "Rust is great!".to_string();

@ -1,9 +1,4 @@
// structs1.rs
//
// Address all the TODOs to make the tests pass! // Address all the TODOs to make the tests pass!
//
// Execute `rustlings hint structs1` or use the `hint` watch subcommand for a
// hint.
struct ColorClassicStruct { struct ColorClassicStruct {
// TODO: Something goes here // TODO: Something goes here

@ -1,9 +1,4 @@
// structs2.rs
//
// Address all the TODOs to make the tests pass! // Address all the TODOs to make the tests pass!
//
// Execute `rustlings hint structs2` or use the `hint` watch subcommand for a
// hint.
#[derive(Debug)] #[derive(Debug)]
struct Order { struct Order {

@ -1,11 +1,6 @@
// structs3.rs
//
// Structs contain data, but can also have logic. In this exercise we have // Structs contain data, but can also have logic. In this exercise we have
// defined the Package struct and we want to test some logic attached to it. // defined the Package struct and we want to test some logic attached to it.
// Make the code compile and the tests pass! // Make the code compile and the tests pass!
//
// Execute `rustlings hint structs3` or use the `hint` watch subcommand for a
// hint.
#[derive(Debug)] #[derive(Debug)]
struct Package { struct Package {

@ -1,7 +1,3 @@
// enums1.rs
//
// No hints this time! ;)
#[derive(Debug)] #[derive(Debug)]
enum Message { enum Message {
// TODO: define a few types of messages as used below // TODO: define a few types of messages as used below

@ -1,8 +1,3 @@
// enums2.rs
//
// Execute `rustlings hint enums2` or use the `hint` watch subcommand for a
// hint.
#[derive(Debug)] #[derive(Debug)]
enum Message { enum Message {
// TODO: define the different variants used below // TODO: define the different variants used below

@ -1,9 +1,4 @@
// enums3.rs
//
// Address all the TODOs to make the tests pass! // Address all the TODOs to make the tests pass!
//
// Execute `rustlings hint enums3` or use the `hint` watch subcommand for a
// hint.
enum Message { enum Message {
// TODO: implement the message variant types based on their usage below // TODO: implement the message variant types based on their usage below

@ -1,9 +1,4 @@
// strings1.rs
//
// Make me compile without changing the function signature! // Make me compile without changing the function signature!
//
// Execute `rustlings hint strings1` or use the `hint` watch subcommand for a
// hint.
fn main() { fn main() {
let answer = current_favorite_color(); let answer = current_favorite_color();

@ -1,9 +1,4 @@
// strings2.rs
//
// Make me compile without changing the function signature! // Make me compile without changing the function signature!
//
// Execute `rustlings hint strings2` or use the `hint` watch subcommand for a
// hint.
fn main() { fn main() {
let word = String::from("green"); // Try not changing this line :) let word = String::from("green"); // Try not changing this line :)

@ -1,8 +1,3 @@
// strings3.rs
//
// Execute `rustlings hint strings3` or use the `hint` watch subcommand for a
// hint.
fn trim_me(input: &str) -> String { fn trim_me(input: &str) -> String {
// TODO: Remove whitespace from both ends of a string! // TODO: Remove whitespace from both ends of a string!
??? ???

@ -1,11 +1,7 @@
// strings4.rs // Ok, here are a bunch of values - some are `String`s, some are `&str`s. Your
//
// Ok, here are a bunch of values-- some are `String`s, some are `&str`s. Your
// task is to call one of these two functions on each value depending on what // task is to call one of these two functions on each value depending on what
// you think each value is. That is, add either `string_slice` or `string` // you think each value is. That is, add either `string_slice` or `string`
// before the parentheses on each line. If you're right, it will compile! // before the parentheses on each line. If you're right, it will compile!
//
// No hints this time!
fn string_slice(arg: &str) { fn string_slice(arg: &str) {
println!("{}", arg); println!("{}", arg);

@ -1,8 +1,3 @@
// modules1.rs
//
// Execute `rustlings hint modules1` or use the `hint` watch subcommand for a
// hint.
mod sausage_factory { mod sausage_factory {
// Don't let anybody outside of this module see this! // Don't let anybody outside of this module see this!
fn get_secret_recipe() -> String { fn get_secret_recipe() -> String {

@ -1,11 +1,6 @@
// modules2.rs
//
// You can bring module paths into scopes and provide new names for them with // You can bring module paths into scopes and provide new names for them with
// the 'use' and 'as' keywords. Fix these 'use' statements to make the code // the 'use' and 'as' keywords. Fix these 'use' statements to make the code
// compile. // compile.
//
// Execute `rustlings hint modules2` or use the `hint` watch subcommand for a
// hint.
mod delicious_snacks { mod delicious_snacks {
// TODO: Fix these use statements // TODO: Fix these use statements

@ -1,12 +1,7 @@
// modules3.rs
//
// You can use the 'use' keyword to bring module paths from modules from // You can use the 'use' keyword to bring module paths from modules from
// anywhere and especially from the Rust standard library into your scope. Bring // anywhere and especially from the Rust standard library into your scope. Bring
// SystemTime and UNIX_EPOCH from the std::time module. Bonus style points if // SystemTime and UNIX_EPOCH from the std::time module. Bonus style points if
// you can do it with one line! // you can do it with one line!
//
// Execute `rustlings hint modules3` or use the `hint` watch subcommand for a
// hint.
// TODO: Complete this use statement // TODO: Complete this use statement
use ??? use ???

@ -1,5 +1,3 @@
// hashmaps1.rs
//
// A basket of fruits in the form of a hash map needs to be defined. The key // A basket of fruits in the form of a hash map needs to be defined. The key
// represents the name of the fruit and the value represents how many of that // represents the name of the fruit and the value represents how many of that
// particular fruit is in the basket. You have to put at least three different // particular fruit is in the basket. You have to put at least three different
@ -7,9 +5,6 @@
// of all the fruits should be at least five. // of all the fruits should be at least five.
// //
// Make me compile and pass the tests! // Make me compile and pass the tests!
//
// Execute `rustlings hint hashmaps1` or use the `hint` watch subcommand for a
// hint.
use std::collections::HashMap; use std::collections::HashMap;

@ -1,5 +1,3 @@
// hashmaps2.rs
//
// We're collecting different fruits to bake a delicious fruit cake. For this, // We're collecting different fruits to bake a delicious fruit cake. For this,
// we have a basket, which we'll represent in the form of a hash map. The key // we have a basket, which we'll represent in the form of a hash map. The key
// represents the name of each fruit we collect and the value represents how // represents the name of each fruit we collect and the value represents how
@ -10,9 +8,6 @@
// to insert any more of these fruits! // to insert any more of these fruits!
// //
// Make me pass the tests! // Make me pass the tests!
//
// Execute `rustlings hint hashmaps2` or use the `hint` watch subcommand for a
// hint.
use std::collections::HashMap; use std::collections::HashMap;

@ -1,5 +1,3 @@
// hashmaps3.rs
//
// A list of scores (one per line) of a soccer match is given. Each line is of // A list of scores (one per line) of a soccer match is given. Each line is of
// the form : "<team_1_name>,<team_2_name>,<team_1_goals>,<team_2_goals>" // the form : "<team_1_name>,<team_2_name>,<team_1_goals>,<team_2_goals>"
// Example: England,France,4,2 (England scored 4 goals, France 2). // Example: England,France,4,2 (England scored 4 goals, France 2).
@ -11,9 +9,6 @@
// complete it to pass the test. // complete it to pass the test.
// //
// Make me pass the tests! // Make me pass the tests!
//
// Execute `rustlings hint hashmaps3` or use the `hint` watch subcommand for a
// hint.
use std::collections::HashMap; use std::collections::HashMap;

@ -1,8 +1,3 @@
// options1.rs
//
// Execute `rustlings hint options1` or use the `hint` watch subcommand for a
// hint.
// This function returns how much icecream there is left in the fridge. // This function returns how much icecream there is left in the fridge.
// If it's before 10PM, there's 5 scoops left. At 10PM, someone eats it // If it's before 10PM, there's 5 scoops left. At 10PM, someone eats it
// all, so there'll be no more left :( // all, so there'll be no more left :(

@ -1,8 +1,3 @@
// options2.rs
//
// Execute `rustlings hint options2` or use the `hint` watch subcommand for a
// hint.
fn main() { fn main() {
// You can optionally experiment here. // You can optionally experiment here.
} }

@ -1,8 +1,3 @@
// options3.rs
//
// Execute `rustlings hint options3` or use the `hint` watch subcommand for a
// hint.
struct Point { struct Point {
x: i32, x: i32,
y: i32, y: i32,

@ -1,13 +1,8 @@
// errors1.rs
//
// This function refuses to generate text to be printed on a nametag if you pass // This function refuses to generate text to be printed on a nametag if you pass
// it an empty string. It'd be nicer if it explained what the problem was, // it an empty string. It'd be nicer if it explained what the problem was,
// instead of just sometimes returning `None`. Thankfully, Rust has a similar // instead of just sometimes returning `None`. Thankfully, Rust has a similar
// construct to `Option` that can be used to express error conditions. Let's use // construct to `Option` that can be used to express error conditions. Let's use
// it! // it!
//
// Execute `rustlings hint errors1` or use the `hint` watch subcommand for a
// hint.
fn main() { fn main() {
// You can optionally experiment here. // You can optionally experiment here.

@ -1,5 +1,3 @@
// errors2.rs
//
// Say we're writing a game where you can buy items with tokens. All items cost // Say we're writing a game where you can buy items with tokens. All items cost
// 5 tokens, and whenever you purchase items there is a processing fee of 1 // 5 tokens, and whenever you purchase items there is a processing fee of 1
// token. A player of the game will type in how many items they want to buy, and // token. A player of the game will type in how many items they want to buy, and
@ -15,9 +13,6 @@
// //
// There are at least two ways to implement this that are both correct-- but one // There are at least two ways to implement this that are both correct-- but one
// is a lot shorter! // is a lot shorter!
//
// Execute `rustlings hint errors2` or use the `hint` watch subcommand for a
// hint.
use std::num::ParseIntError; use std::num::ParseIntError;

@ -1,11 +1,6 @@
// errors3.rs
//
// This is a program that is trying to use a completed version of the // This is a program that is trying to use a completed version of the
// `total_cost` function from the previous exercise. It's not working though! // `total_cost` function from the previous exercise. It's not working though!
// Why not? What should we do to fix it? // Why not? What should we do to fix it?
//
// Execute `rustlings hint errors3` or use the `hint` watch subcommand for a
// hint.
use std::num::ParseIntError; use std::num::ParseIntError;

@ -1,8 +1,3 @@
// errors4.rs
//
// Execute `rustlings hint errors4` or use the `hint` watch subcommand for a
// hint.
#[derive(PartialEq, Debug)] #[derive(PartialEq, Debug)]
struct PositiveNonzeroInteger(u64); struct PositiveNonzeroInteger(u64);
@ -23,12 +18,17 @@ fn main() {
// You can optionally experiment here. // You can optionally experiment here.
} }
#[test] #[cfg(test)]
fn test_creation() { mod tests {
assert!(PositiveNonzeroInteger::new(10).is_ok()); use super::*;
assert_eq!(
Err(CreationError::Negative), #[test]
PositiveNonzeroInteger::new(-10) fn test_creation() {
); assert!(PositiveNonzeroInteger::new(10).is_ok());
assert_eq!(Err(CreationError::Zero), PositiveNonzeroInteger::new(0)); assert_eq!(
Err(CreationError::Negative),
PositiveNonzeroInteger::new(-10)
);
assert_eq!(Err(CreationError::Zero), PositiveNonzeroInteger::new(0));
}
} }

@ -1,5 +1,3 @@
// errors5.rs
//
// This program uses an altered version of the code from errors4. // This program uses an altered version of the code from errors4.
// //
// This exercise uses some concepts that we won't get to until later in the // This exercise uses some concepts that we won't get to until later in the
@ -18,9 +16,6 @@
// //
// What can we use to describe both errors? In other words, is there a trait // What can we use to describe both errors? In other words, is there a trait
// which both errors implement? // which both errors implement?
//
// Execute `rustlings hint errors5` or use the `hint` watch subcommand for a
// hint.
use std::error; use std::error;
use std::fmt; use std::fmt;

@ -1,13 +1,8 @@
// errors6.rs
//
// Using catch-all error types like `Box<dyn error::Error>` isn't recommended // Using catch-all error types like `Box<dyn error::Error>` isn't recommended
// for library code, where callers might want to make decisions based on the // for library code, where callers might want to make decisions based on the
// error content, instead of printing it out or propagating it further. Here, we // error content, instead of printing it out or propagating it further. Here, we
// define a custom error type to make it possible for callers to decide what to // define a custom error type to make it possible for callers to decide what to
// do next when our function returns an error. // do next when our function returns an error.
//
// Execute `rustlings hint errors6` or use the `hint` watch subcommand for a
// hint.
use std::num::ParseIntError; use std::num::ParseIntError;

@ -1,10 +1,5 @@
// generics1.rs
//
// This shopping list program isn't compiling! Use your knowledge of generics to // This shopping list program isn't compiling! Use your knowledge of generics to
// fix it. // fix it.
//
// Execute `rustlings hint generics1` or use the `hint` watch subcommand for a
// hint.
fn main() { fn main() {
let mut shopping_list: Vec<?> = Vec::new(); let mut shopping_list: Vec<?> = Vec::new();

@ -1,10 +1,5 @@
// generics2.rs
//
// This powerful wrapper provides the ability to store a positive integer value. // This powerful wrapper provides the ability to store a positive integer value.
// Rewrite it using generics so that it supports wrapping ANY type. // Rewrite it using generics so that it supports wrapping ANY type.
//
// Execute `rustlings hint generics2` or use the `hint` watch subcommand for a
// hint.
struct Wrapper { struct Wrapper {
value: u32, value: u32,

@ -1,11 +1,6 @@
// traits1.rs
//
// Time to implement some traits! Your task is to implement the trait // Time to implement some traits! Your task is to implement the trait
// `AppendBar` for the type `String`. The trait AppendBar has only one function, // `AppendBar` for the type `String`. The trait AppendBar has only one function,
// which appends "Bar" to any object implementing this trait. // which appends "Bar" to any object implementing this trait.
//
// Execute `rustlings hint traits1` or use the `hint` watch subcommand for a
// hint.
trait AppendBar { trait AppendBar {
fn append_bar(self) -> Self; fn append_bar(self) -> Self;

@ -1,12 +1,8 @@
// traits2.rs
//
// Your task is to implement the trait `AppendBar` for a vector of strings. To // Your task is to implement the trait `AppendBar` for a vector of strings. To
// implement this trait, consider for a moment what it means to 'append "Bar"' // implement this trait, consider for a moment what it means to 'append "Bar"'
// to a vector of strings. // to a vector of strings.
// //
// No boiler plate code this time, you can do this! // No boiler plate code this time, you can do this!
//
// Execute `rustlings hint traits2` or use the `hint` watch subcommand for a hint.
trait AppendBar { trait AppendBar {
fn append_bar(self) -> Self; fn append_bar(self) -> Self;

@ -1,12 +1,7 @@
// traits3.rs
//
// Your task is to implement the Licensed trait for both structures and have // Your task is to implement the Licensed trait for both structures and have
// them return the same information without writing the same function twice. // them return the same information without writing the same function twice.
// //
// Consider what you can add to the Licensed trait. // Consider what you can add to the Licensed trait.
//
// Execute `rustlings hint traits3` or use the `hint` watch subcommand for a
// hint.
pub trait Licensed { pub trait Licensed {
fn licensing_info(&self) -> String; fn licensing_info(&self) -> String;

@ -1,11 +1,6 @@
// traits4.rs
//
// Your task is to replace the '??' sections so the code compiles. // Your task is to replace the '??' sections so the code compiles.
// //
// Don't change any line other than the marked one. // Don't change any line other than the marked one.
//
// Execute `rustlings hint traits4` or use the `hint` watch subcommand for a
// hint.
pub trait Licensed { pub trait Licensed {
fn licensing_info(&self) -> String { fn licensing_info(&self) -> String {

@ -1,11 +1,6 @@
// traits5.rs
//
// Your task is to replace the '??' sections so the code compiles. // Your task is to replace the '??' sections so the code compiles.
// //
// Don't change any line other than the marked one. // Don't change any line other than the marked one.
//
// Execute `rustlings hint traits5` or use the `hint` watch subcommand for a
// hint.
pub trait SomeTrait { pub trait SomeTrait {
fn some_function(&self) -> bool { fn some_function(&self) -> bool {

@ -1,12 +1,7 @@
// lifetimes1.rs
//
// The Rust compiler needs to know how to check whether supplied references are // The Rust compiler needs to know how to check whether supplied references are
// valid, so that it can let the programmer know if a reference is at risk of // valid, so that it can let the programmer know if a reference is at risk of
// going out of scope before it is used. Remember, references are borrows and do // going out of scope before it is used. Remember, references are borrows and do
// not own their own data. What if their owner goes out of scope? // not own their own data. What if their owner goes out of scope?
//
// Execute `rustlings hint lifetimes1` or use the `hint` watch subcommand for a
// hint.
fn longest(x: &str, y: &str) -> &str { fn longest(x: &str, y: &str) -> &str {
if x.len() > y.len() { if x.len() > y.len() {

@ -1,10 +1,5 @@
// lifetimes2.rs
//
// So if the compiler is just validating the references passed to the annotated // So if the compiler is just validating the references passed to the annotated
// parameters and the return type, what do we need to change? // parameters and the return type, what do we need to change?
//
// Execute `rustlings hint lifetimes2` or use the `hint` watch subcommand for a
// hint.
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str { fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() { if x.len() > y.len() {

@ -1,9 +1,4 @@
// lifetimes3.rs
//
// Lifetimes are also needed when structs hold references. // Lifetimes are also needed when structs hold references.
//
// Execute `rustlings hint lifetimes3` or use the `hint` watch subcommand for a
// hint.
struct Book { struct Book {
author: &str, author: &str,
@ -13,7 +8,10 @@ struct Book {
fn main() { fn main() {
let name = String::from("Jill Smith"); let name = String::from("Jill Smith");
let title = String::from("Fish Flying"); let title = String::from("Fish Flying");
let book = Book { author: &name, title: &title }; let book = Book {
author: &name,
title: &title,
};
println!("{} by {}", book.title, book.author); println!("{} by {}", book.title, book.author);
} }

@ -1,14 +1,9 @@
// tests1.rs
//
// Tests are important to ensure that your code does what you think it should // Tests are important to ensure that your code does what you think it should
// do. Tests can be run on this file with the following command: rustlings run // do. Tests can be run on this file with the following command: rustlings run
// tests1 // tests1
// //
// This test has a problem with it -- make the test compile! Make the test pass! // This test has a problem with it -- make the test compile! Make the test pass!
// Make the test fail! // Make the test fail!
//
// Execute `rustlings hint tests1` or use the `hint` watch subcommand for a
// hint.
fn main() { fn main() {
// You can optionally experiment here. // You can optionally experiment here.

@ -1,10 +1,5 @@
// tests2.rs
//
// This test has a problem with it -- make the test compile! Make the test pass! // This test has a problem with it -- make the test compile! Make the test pass!
// Make the test fail! // Make the test fail!
//
// Execute `rustlings hint tests2` or use the `hint` watch subcommand for a
// hint.
fn main() { fn main() {
// You can optionally experiment here. // You can optionally experiment here.

@ -1,11 +1,6 @@
// tests3.rs
//
// This test isn't testing our function -- make it do that in such a way that // This test isn't testing our function -- make it do that in such a way that
// the test passes. Then write a second test that tests whether we get the // the test passes. Then write a second test that tests whether we get the
// result we expect to get when we call `is_even(5)`. // result we expect to get when we call `is_even(5)`.
//
// Execute `rustlings hint tests3` or use the `hint` watch subcommand for a
// hint.
pub fn is_even(num: i32) -> bool { pub fn is_even(num: i32) -> bool {
num % 2 == 0 num % 2 == 0

@ -1,9 +1,4 @@
// tests4.rs
//
// Make sure that we're testing for the correct conditions! // Make sure that we're testing for the correct conditions!
//
// Execute `rustlings hint tests4` or use the `hint` watch subcommand for a
// hint.
struct Rectangle { struct Rectangle {
width: i32, width: i32,

@ -1,24 +1,28 @@
// iterators1.rs
//
// When performing operations on elements within a collection, iterators are // When performing operations on elements within a collection, iterators are
// essential. This module helps you get familiar with the structure of using an // essential. This module helps you get familiar with the structure of using an
// iterator and how to go through elements within an iterable collection. // iterator and how to go through elements within an iterable collection.
// //
// Make me compile by filling in the `???`s // Make me compile by filling in the `???`s
//
// Execute `rustlings hint iterators1` or use the `hint` watch subcommand for a
// hint.
#[test]
fn main() { fn main() {
let my_fav_fruits = vec!["banana", "custard apple", "avocado", "peach", "raspberry"]; // You can optionally experiment here.
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn iterators() {
let my_fav_fruits = vec!["banana", "custard apple", "avocado", "peach", "raspberry"];
let mut my_iterable_fav_fruits = ???; // TODO: Step 1 let mut my_iterable_fav_fruits = ???; // TODO: Step 1
assert_eq!(my_iterable_fav_fruits.next(), Some(&"banana")); assert_eq!(my_iterable_fav_fruits.next(), Some(&"banana"));
assert_eq!(my_iterable_fav_fruits.next(), ???); // TODO: Step 2 assert_eq!(my_iterable_fav_fruits.next(), ???); // TODO: Step 2
assert_eq!(my_iterable_fav_fruits.next(), Some(&"avocado")); assert_eq!(my_iterable_fav_fruits.next(), Some(&"avocado"));
assert_eq!(my_iterable_fav_fruits.next(), ???); // TODO: Step 3 assert_eq!(my_iterable_fav_fruits.next(), ???); // TODO: Step 3
assert_eq!(my_iterable_fav_fruits.next(), Some(&"raspberry")); assert_eq!(my_iterable_fav_fruits.next(), Some(&"raspberry"));
assert_eq!(my_iterable_fav_fruits.next(), ???); // TODO: Step 4 assert_eq!(my_iterable_fav_fruits.next(), ???); // TODO: Step 4
}
} }

@ -1,10 +1,5 @@
// iterators2.rs
//
// In this exercise, you'll learn some of the unique advantages that iterators // In this exercise, you'll learn some of the unique advantages that iterators
// can offer. Follow the steps to complete the exercise. // can offer. Follow the steps to complete the exercise.
//
// Execute `rustlings hint iterators2` or use the `hint` watch subcommand for a
// hint.
// Step 1. // Step 1.
// Complete the `capitalize_first` function. // Complete the `capitalize_first` function.

@ -1,13 +1,8 @@
// iterators3.rs
//
// This is a bigger exercise than most of the others! You can do it! Here is // This is a bigger exercise than most of the others! You can do it! Here is
// your mission, should you choose to accept it: // your mission, should you choose to accept it:
// 1. Complete the divide function to get the first four tests to pass. // 1. Complete the divide function to get the first four tests to pass.
// 2. Get the remaining tests to pass by completing the result_with_list and // 2. Get the remaining tests to pass by completing the result_with_list and
// list_of_results functions. // list_of_results functions.
//
// Execute `rustlings hint iterators3` or use the `hint` watch subcommand for a
// hint.
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq)]
pub enum DivisionError { pub enum DivisionError {

@ -1,8 +1,3 @@
// iterators4.rs
//
// Execute `rustlings hint iterators4` or use the `hint` watch subcommand for a
// hint.
pub fn factorial(num: u64) -> u64 { pub fn factorial(num: u64) -> u64 {
// Complete this function to return the factorial of num // Complete this function to return the factorial of num
// Do not use: // Do not use:
@ -12,7 +7,6 @@ pub fn factorial(num: u64) -> u64 {
// - additional variables // - additional variables
// For an extra challenge, don't use: // For an extra challenge, don't use:
// - recursion // - recursion
// Execute `rustlings hint iterators4` for hints.
} }
fn main() { fn main() {

@ -1,5 +1,3 @@
// iterators5.rs
//
// Let's define a simple model to track Rustlings exercise progress. Progress // Let's define a simple model to track Rustlings exercise progress. Progress
// will be modelled using a hash map. The name of the exercise is the key and // will be modelled using a hash map. The name of the exercise is the key and
// the progress is the value. Two counting functions were created to count the // the progress is the value. Two counting functions were created to count the
@ -7,9 +5,6 @@
// functionality using iterators. Try not to use imperative loops (for, while). // functionality using iterators. Try not to use imperative loops (for, while).
// Only the two iterator methods (count_iterator and count_collection_iterator) // Only the two iterator methods (count_iterator and count_collection_iterator)
// need to be modified. // need to be modified.
//
// Execute `rustlings hint iterators5` or use the `hint` watch subcommand for a
// hint.
use std::collections::HashMap; use std::collections::HashMap;

@ -1,5 +1,3 @@
// arc1.rs
//
// In this exercise, we are given a Vec of u32 called "numbers" with values // In this exercise, we are given a Vec of u32 called "numbers" with values
// ranging from 0 to 99 -- [ 0, 1, 2, ..., 98, 99 ] We would like to use this // ranging from 0 to 99 -- [ 0, 1, 2, ..., 98, 99 ] We would like to use this
// set of numbers within 8 different threads simultaneously. Each thread is // set of numbers within 8 different threads simultaneously. Each thread is
@ -18,8 +16,6 @@
// first TODO comment is, and create an initial binding for `child_numbers` // first TODO comment is, and create an initial binding for `child_numbers`
// where the second TODO comment is. Try not to create any copies of the // where the second TODO comment is. Try not to create any copies of the
// `numbers` Vec! // `numbers` Vec!
//
// Execute `rustlings hint arc1` or use the `hint` watch subcommand for a hint.
#![forbid(unused_imports)] // Do not change this, (or the next) line. #![forbid(unused_imports)] // Do not change this, (or the next) line.
use std::sync::Arc; use std::sync::Arc;

@ -1,5 +1,3 @@
// box1.rs
//
// At compile time, Rust needs to know how much space a type takes up. This // At compile time, Rust needs to know how much space a type takes up. This
// becomes problematic for recursive types, where a value can have as part of // becomes problematic for recursive types, where a value can have as part of
// itself another value of the same type. To get around the issue, we can use a // itself another value of the same type. To get around the issue, we can use a
@ -15,8 +13,6 @@
// Step 2: create both empty and non-empty cons lists by replacing `todo!()` // Step 2: create both empty and non-empty cons lists by replacing `todo!()`
// //
// Note: the tests should not be changed // Note: the tests should not be changed
//
// Execute `rustlings hint box1` or use the `hint` watch subcommand for a hint.
#[derive(PartialEq, Debug)] #[derive(PartialEq, Debug)]
pub enum List { pub enum List {

@ -1,5 +1,3 @@
// cow1.rs
//
// This exercise explores the Cow, or Clone-On-Write type. Cow is a // This exercise explores the Cow, or Clone-On-Write type. Cow is a
// clone-on-write smart pointer. It can enclose and provide immutable access to // clone-on-write smart pointer. It can enclose and provide immutable access to
// borrowed data, and clone the data lazily when mutation or ownership is // borrowed data, and clone the data lazily when mutation or ownership is
@ -9,8 +7,6 @@
// This exercise is meant to show you what to expect when passing data to Cow. // This exercise is meant to show you what to expect when passing data to Cow.
// Fix the unit tests by checking for Cow::Owned(_) and Cow::Borrowed(_) at the // Fix the unit tests by checking for Cow::Owned(_) and Cow::Borrowed(_) at the
// TODO markers. // TODO markers.
//
// Execute `rustlings hint cow1` or use the `hint` watch subcommand for a hint.
use std::borrow::Cow; use std::borrow::Cow;

@ -1,5 +1,3 @@
// rc1.rs
//
// In this exercise, we want to express the concept of multiple owners via the // In this exercise, we want to express the concept of multiple owners via the
// Rc<T> type. This is a model of our solar system - there is a Sun type and // Rc<T> type. This is a model of our solar system - there is a Sun type and
// multiple Planets. The Planets take ownership of the sun, indicating that they // multiple Planets. The Planets take ownership of the sun, indicating that they
@ -7,8 +5,6 @@
// //
// Make this code compile by using the proper Rc primitives to express that the // Make this code compile by using the proper Rc primitives to express that the
// sun has multiple owners. // sun has multiple owners.
//
// Execute `rustlings hint rc1` or use the `hint` watch subcommand for a hint.
use std::rc::Rc; use std::rc::Rc;
@ -33,71 +29,80 @@ impl Planet {
} }
} }
#[test]
fn main() { fn main() {
let sun = Rc::new(Sun {}); // You can optionally experiment here.
println!("reference count = {}", Rc::strong_count(&sun)); // 1 reference }
let mercury = Planet::Mercury(Rc::clone(&sun)); #[cfg(test)]
println!("reference count = {}", Rc::strong_count(&sun)); // 2 references mod tests {
mercury.details(); use super::*;
let venus = Planet::Venus(Rc::clone(&sun)); #[test]
println!("reference count = {}", Rc::strong_count(&sun)); // 3 references fn rc1() {
venus.details(); let sun = Rc::new(Sun {});
println!("reference count = {}", Rc::strong_count(&sun)); // 1 reference
let earth = Planet::Earth(Rc::clone(&sun)); let mercury = Planet::Mercury(Rc::clone(&sun));
println!("reference count = {}", Rc::strong_count(&sun)); // 4 references println!("reference count = {}", Rc::strong_count(&sun)); // 2 references
earth.details(); mercury.details();
let mars = Planet::Mars(Rc::clone(&sun)); let venus = Planet::Venus(Rc::clone(&sun));
println!("reference count = {}", Rc::strong_count(&sun)); // 5 references println!("reference count = {}", Rc::strong_count(&sun)); // 3 references
mars.details(); venus.details();
let jupiter = Planet::Jupiter(Rc::clone(&sun)); let earth = Planet::Earth(Rc::clone(&sun));
println!("reference count = {}", Rc::strong_count(&sun)); // 6 references println!("reference count = {}", Rc::strong_count(&sun)); // 4 references
jupiter.details(); earth.details();
// TODO let mars = Planet::Mars(Rc::clone(&sun));
let saturn = Planet::Saturn(Rc::new(Sun {})); println!("reference count = {}", Rc::strong_count(&sun)); // 5 references
println!("reference count = {}", Rc::strong_count(&sun)); // 7 references mars.details();
saturn.details();
// TODO let jupiter = Planet::Jupiter(Rc::clone(&sun));
let uranus = Planet::Uranus(Rc::new(Sun {})); println!("reference count = {}", Rc::strong_count(&sun)); // 6 references
println!("reference count = {}", Rc::strong_count(&sun)); // 8 references jupiter.details();
uranus.details();
// TODO // TODO
let neptune = Planet::Neptune(Rc::new(Sun {})); let saturn = Planet::Saturn(Rc::new(Sun {}));
println!("reference count = {}", Rc::strong_count(&sun)); // 9 references println!("reference count = {}", Rc::strong_count(&sun)); // 7 references
neptune.details(); saturn.details();
assert_eq!(Rc::strong_count(&sun), 9); // TODO
let uranus = Planet::Uranus(Rc::new(Sun {}));
println!("reference count = {}", Rc::strong_count(&sun)); // 8 references
uranus.details();
drop(neptune); // TODO
println!("reference count = {}", Rc::strong_count(&sun)); // 8 references let neptune = Planet::Neptune(Rc::new(Sun {}));
println!("reference count = {}", Rc::strong_count(&sun)); // 9 references
neptune.details();
drop(uranus); assert_eq!(Rc::strong_count(&sun), 9);
println!("reference count = {}", Rc::strong_count(&sun)); // 7 references
drop(saturn); drop(neptune);
println!("reference count = {}", Rc::strong_count(&sun)); // 6 references println!("reference count = {}", Rc::strong_count(&sun)); // 8 references
drop(jupiter); drop(uranus);
println!("reference count = {}", Rc::strong_count(&sun)); // 5 references println!("reference count = {}", Rc::strong_count(&sun)); // 7 references
drop(mars); drop(saturn);
println!("reference count = {}", Rc::strong_count(&sun)); // 4 references println!("reference count = {}", Rc::strong_count(&sun)); // 6 references
// TODO drop(jupiter);
println!("reference count = {}", Rc::strong_count(&sun)); // 3 references println!("reference count = {}", Rc::strong_count(&sun)); // 5 references
// TODO drop(mars);
println!("reference count = {}", Rc::strong_count(&sun)); // 2 references println!("reference count = {}", Rc::strong_count(&sun)); // 4 references
// TODO // TODO
println!("reference count = {}", Rc::strong_count(&sun)); // 1 reference println!("reference count = {}", Rc::strong_count(&sun)); // 3 references
assert_eq!(Rc::strong_count(&sun), 1); // TODO
println!("reference count = {}", Rc::strong_count(&sun)); // 2 references
// TODO
println!("reference count = {}", Rc::strong_count(&sun)); // 1 reference
assert_eq!(Rc::strong_count(&sun), 1);
}
} }

@ -1,12 +1,7 @@
// threads1.rs
//
// This program spawns multiple threads that each run for at least 250ms, and // This program spawns multiple threads that each run for at least 250ms, and
// each thread returns how much time they took to complete. The program should // each thread returns how much time they took to complete. The program should
// wait until all the spawned threads have finished and should collect their // wait until all the spawned threads have finished and should collect their
// return values into a vector. // return values into a vector.
//
// Execute `rustlings hint threads1` or use the `hint` watch subcommand for a
// hint.
use std::thread; use std::thread;
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};

@ -1,11 +1,6 @@
// threads2.rs
//
// Building on the last exercise, we want all of the threads to complete their // Building on the last exercise, we want all of the threads to complete their
// work but this time the spawned threads need to be in charge of updating a // work but this time the spawned threads need to be in charge of updating a
// shared value: JobStatus.jobs_completed // shared value: JobStatus.jobs_completed
//
// Execute `rustlings hint threads2` or use the `hint` watch subcommand for a
// hint.
use std::sync::Arc; use std::sync::Arc;
use std::thread; use std::thread;

@ -1,8 +1,3 @@
// threads3.rs
//
// Execute `rustlings hint threads3` or use the `hint` watch subcommand for a
// hint.
use std::sync::mpsc; use std::sync::mpsc;
use std::sync::Arc; use std::sync::Arc;
use std::thread; use std::thread;
@ -42,20 +37,29 @@ fn send_tx(q: Queue, tx: mpsc::Sender<u32>) -> () {
}); });
} }
#[test]
fn main() { fn main() {
let (tx, rx) = mpsc::channel(); // You can optionally experiment here.
let queue = Queue::new(); }
let queue_length = queue.length;
send_tx(queue, tx); #[cfg(test)]
mod tests {
use super::*;
let mut total_received: u32 = 0; #[test]
for received in rx { fn threads3() {
println!("Got: {}", received); let (tx, rx) = mpsc::channel();
total_received += 1; let queue = Queue::new();
} let queue_length = queue.length;
send_tx(queue, tx);
println!("total numbers received: {}", total_received); let mut total_received: u32 = 0;
assert_eq!(total_received, queue_length) for received in rx {
println!("Got: {}", received);
total_received += 1;
}
println!("total numbers received: {}", total_received);
assert_eq!(total_received, queue_length)
}
} }

@ -1,8 +1,3 @@
// macros1.rs
//
// Execute `rustlings hint macros1` or use the `hint` watch subcommand for a
// hint.
macro_rules! my_macro { macro_rules! my_macro {
() => { () => {
println!("Check out my macro!"); println!("Check out my macro!");

@ -1,8 +1,3 @@
// macros2.rs
//
// Execute `rustlings hint macros2` or use the `hint` watch subcommand for a
// hint.
fn main() { fn main() {
my_macro!(); my_macro!();
} }

@ -1,9 +1,4 @@
// macros3.rs
//
// Make me compile, without taking the macro out of the module! // Make me compile, without taking the macro out of the module!
//
// Execute `rustlings hint macros3` or use the `hint` watch subcommand for a
// hint.
mod macros { mod macros {
macro_rules! my_macro { macro_rules! my_macro {

@ -1,8 +1,3 @@
// macros4.rs
//
// Execute `rustlings hint macros4` or use the `hint` watch subcommand for a
// hint.
#[rustfmt::skip] #[rustfmt::skip]
macro_rules! my_macro { macro_rules! my_macro {
() => { () => {

@ -1,13 +1,8 @@
// clippy1.rs
//
// The Clippy tool is a collection of lints to analyze your code so you can // The Clippy tool is a collection of lints to analyze your code so you can
// catch common mistakes and improve your Rust code. // catch common mistakes and improve your Rust code.
// //
// For these exercises the code will fail to compile when there are Clippy // 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. // warnings. Check Clippy's suggestions from the output to solve the exercise.
//
// Execute `rustlings hint clippy1` or use the `hint` watch subcommand for a
// hint.
use std::f32; use std::f32;

@ -1,8 +1,3 @@
// clippy2.rs
//
// Execute `rustlings hint clippy2` or use the `hint` watch subcommand for a
// hint.
fn main() { fn main() {
let mut res = 42; let mut res = 42;
let option = Some(12); let option = Some(12);

@ -1,7 +1,4 @@
// clippy3.rs
//
// Here's a couple more easy Clippy fixes, so you can see its utility. // Here's a couple more easy Clippy fixes, so you can see its utility.
// No hints.
#[allow(unused_variables, unused_assignments)] #[allow(unused_variables, unused_assignments)]
fn main() { fn main() {

@ -1,11 +1,6 @@
// as_ref_mut.rs
//
// AsRef and AsMut allow for cheap reference-to-reference conversions. Read more // AsRef and AsMut allow for cheap reference-to-reference conversions. Read more
// about them at https://doc.rust-lang.org/std/convert/trait.AsRef.html and // 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. // https://doc.rust-lang.org/std/convert/trait.AsMut.html, respectively.
//
// Execute `rustlings hint as_ref_mut` or use the `hint` watch subcommand for a
// hint.
// Obtain the number of bytes (not characters) in the given argument. // Obtain the number of bytes (not characters) in the given argument.
// TODO: Add the AsRef trait appropriately as a trait bound. // TODO: Add the AsRef trait appropriately as a trait bound.

@ -1,11 +1,6 @@
// from_into.rs
//
// The From trait is used for value-to-value conversions. If From is implemented // The From trait is used for value-to-value conversions. If From is implemented
// correctly for a type, the Into trait should work conversely. You can read // correctly for a type, the Into trait should work conversely. You can read
// more about it at https://doc.rust-lang.org/std/convert/trait.From.html // more about it at https://doc.rust-lang.org/std/convert/trait.From.html
//
// Execute `rustlings hint from_into` or use the `hint` watch subcommand for a
// hint.
#[derive(Debug)] #[derive(Debug)]
struct Person { struct Person {
@ -24,7 +19,6 @@ impl Default for Person {
} }
} }
// Your task is to complete this implementation in order for the line `let p1 = // Your task is to complete this implementation in order for the line `let p1 =
// Person::from("Mark,20")` to compile. Please note that you'll need to parse the // Person::from("Mark,20")` to compile. Please note that you'll need to parse the
// age component into a `usize` with something like `"4".parse::<usize>()`. The // age component into a `usize` with something like `"4".parse::<usize>()`. The

@ -1,13 +1,8 @@
// from_str.rs
//
// This is similar to from_into.rs, but this time we'll implement `FromStr` and // This is similar to from_into.rs, but this time we'll implement `FromStr` and
// return errors instead of falling back to a default value. Additionally, upon // return errors instead of falling back to a default value. Additionally, upon
// implementing FromStr, you can use the `parse` method on strings to generate // implementing FromStr, you can use the `parse` method on strings to generate
// an object of the implementor type. You can read more about it at // an object of the implementor type. You can read more about it at
// https://doc.rust-lang.org/std/str/trait.FromStr.html // https://doc.rust-lang.org/std/str/trait.FromStr.html
//
// Execute `rustlings hint from_str` or use the `hint` watch subcommand for a
// hint.
use std::num::ParseIntError; use std::num::ParseIntError;
use std::str::FromStr; use std::str::FromStr;

@ -1,13 +1,8 @@
// try_from_into.rs
//
// TryFrom is a simple and safe type conversion that may fail in a controlled // TryFrom is a simple and safe type conversion that may fail in a controlled
// way under some circumstances. Basically, this is the same as From. The main // way under some circumstances. Basically, this is the same as From. The main
// difference is that this should return a Result type instead of the target // difference is that this should return a Result type instead of the target
// type itself. You can read more about it at // type itself. You can read more about it at
// https://doc.rust-lang.org/std/convert/trait.TryFrom.html // https://doc.rust-lang.org/std/convert/trait.TryFrom.html
//
// Execute `rustlings hint try_from_into` or use the `hint` watch subcommand for
// a hint.
use std::convert::{TryFrom, TryInto}; use std::convert::{TryFrom, TryInto};

@ -1,14 +1,9 @@
// using_as.rs
//
// Type casting in Rust is done via the usage of the `as` operator. Please note // Type casting in Rust is done via the usage of the `as` operator. Please note
// that the `as` operator is not only used when type casting. It also helps with // that the `as` operator is not only used when type casting. It also helps with
// renaming imports. // renaming imports.
// //
// The goal is to make sure that the division does not fail to compile and // The goal is to make sure that the division does not fail to compile and
// returns the proper type. // returns the proper type.
//
// Execute `rustlings hint using_as` or use the `hint` watch subcommand for a
// hint.
fn average(values: &[f64]) -> f64 { fn average(values: &[f64]) -> f64 {
let total = values.iter().sum::<f64>(); let total = values.iter().sum::<f64>();

@ -1,5 +1,3 @@
// quiz1.rs
//
// This is a quiz for the following sections: // This is a quiz for the following sections:
// - Variables // - Variables
// - Functions // - Functions
@ -10,8 +8,6 @@
// - If Mary buys more than 40 apples, each apple only costs 1 rustbuck! // - If Mary buys more than 40 apples, each apple only costs 1 rustbuck!
// Write a function that calculates the price of an order of apples given the // Write a function that calculates the price of an order of apples given the
// quantity bought. // quantity bought.
//
// No hints this time ;)
// Put your function here! // Put your function here!
// fn calculate_price_of_apples { // fn calculate_price_of_apples {
@ -20,16 +16,21 @@ fn main() {
// You can optionally experiment here. // You can optionally experiment here.
} }
// Don't modify this function! #[cfg(test)]
#[test] mod tests {
fn verify_test() { use super::*;
let price1 = calculate_price_of_apples(35);
let price2 = calculate_price_of_apples(40); // Don't modify this test!
let price3 = calculate_price_of_apples(41); #[test]
let price4 = calculate_price_of_apples(65); fn verify_test() {
let price1 = calculate_price_of_apples(35);
let price2 = calculate_price_of_apples(40);
let price3 = calculate_price_of_apples(41);
let price4 = calculate_price_of_apples(65);
assert_eq!(70, price1); assert_eq!(70, price1);
assert_eq!(80, price2); assert_eq!(80, price2);
assert_eq!(41, price3); assert_eq!(41, price3);
assert_eq!(65, price4); assert_eq!(65, price4);
}
} }

@ -1,5 +1,3 @@
// quiz2.rs
//
// This is a quiz for the following sections: // This is a quiz for the following sections:
// - Strings // - Strings
// - Vecs // - Vecs
@ -17,8 +15,6 @@
// - The input is going to be a Vector of a 2-length tuple, // - The input is going to be a Vector of a 2-length tuple,
// the first element is the string, the second one is the command. // the first element is the string, the second one is the command.
// - The output element is going to be a Vector of strings. // - The output element is going to be a Vector of strings.
//
// No hints this time!
pub enum Command { pub enum Command {
Uppercase, Uppercase,

@ -1,5 +1,3 @@
// quiz3.rs
//
// This quiz tests: // This quiz tests:
// - Generics // - Generics
// - Traits // - Traits
@ -13,8 +11,6 @@
// Make the necessary code changes in the struct ReportCard and the impl block // Make the necessary code changes in the struct ReportCard and the impl block
// to support alphabetical report cards. Change the Grade in the second test to // to support alphabetical report cards. Change the Grade in the second test to
// "A+" to show that your changes allow alphabetical grades. // "A+" to show that your changes allow alphabetical grades.
//
// Execute `rustlings hint quiz3` or use the `hint` watch subcommand for a hint.
pub struct ReportCard { pub struct ReportCard {
pub grade: f32, pub grade: f32,

Loading…
Cancel
Save