My solution to rustlings course

This commit is contained in:
Marco 2023-09-10 18:38:07 +02:00
parent 8d0aa11a35
commit b9117282d1
99 changed files with 456 additions and 523 deletions

181
README.md
View File

@ -1,180 +1 @@
<div class="oranda-hide"> These are my solutions to the rustlings course
# rustlings 🦀❤️
</div>
Greetings and welcome to `rustlings`. This project contains small exercises to get you used to reading and writing Rust code. This includes reading and responding to compiler messages!
_...looking for the old, web-based version of Rustlings? Try [here](https://github.com/rust-lang/rustlings/tree/rustlings-1)_
Alternatively, for a first-time Rust learner, there are several other resources:
- [The Book](https://doc.rust-lang.org/book/index.html) - The most comprehensive resource for learning Rust, but a bit theoretical sometimes. You will be using this along with Rustlings!
- [Rust By Example](https://doc.rust-lang.org/rust-by-example/index.html) - Learn Rust by solving little exercises! It's almost like `rustlings`, but online
## Getting Started
_Note: If you're on MacOS, make sure you've installed Xcode and its developer tools by typing `xcode-select --install`._
_Note: If you're on Linux, make sure you've installed gcc. Deb: `sudo apt install gcc`. Yum: `sudo yum -y install gcc`._
You will need to have Rust installed. You can get it by visiting <https://rustup.rs>. This'll also install Cargo, Rust's package/project manager.
## MacOS/Linux
Just run:
```bash
curl -L https://raw.githubusercontent.com/rust-lang/rustlings/main/install.sh | bash
```
Or if you want it to be installed to a different path:
```bash
curl -L https://raw.githubusercontent.com/rust-lang/rustlings/main/install.sh | bash -s mypath/
```
This will install Rustlings and give you access to the `rustlings` command. Run it to get started!
### Nix
Basically: Clone the repository at the latest tag, finally run `nix develop` or `nix-shell`.
```bash
# find out the latest version at https://github.com/rust-lang/rustlings/releases/latest (on edit 5.6.1)
git clone -b 5.6.1 --depth 1 https://github.com/rust-lang/rustlings
cd rustlings
# if nix version > 2.3
nix develop
# if nix version <= 2.3
nix-shell
```
## Windows
In PowerShell (Run as Administrator), set `ExecutionPolicy` to `RemoteSigned`:
```ps1
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
```
Then, you can run:
```ps1
Start-BitsTransfer -Source https://raw.githubusercontent.com/rust-lang/rustlings/main/install.ps1 -Destination $env:TMP/install_rustlings.ps1; Unblock-File $env:TMP/install_rustlings.ps1; Invoke-Expression $env:TMP/install_rustlings.ps1
```
To install Rustlings. Same as on MacOS/Linux, you will have access to the `rustlings` command after it. Keep in mind that this works best in PowerShell, and any other terminals may give you errors.
If you get a permission denied message, you might have to exclude the directory where you cloned Rustlings in your antivirus.
## Browser
[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/rust-lang/rustlings)
[![Open Rustlings On Codespaces](https://github.com/codespaces/badge.svg)](https://github.com/codespaces/new/?repo=rust-lang%2Frustlings&ref=main)
## Manually
Basically: Clone the repository at the latest tag, run `cargo install --path .`.
```bash
# find out the latest version at https://github.com/rust-lang/rustlings/releases/latest (on edit 5.6.1)
git clone -b 5.6.1 --depth 1 https://github.com/rust-lang/rustlings
cd rustlings
cargo install --force --path .
```
If there are installation errors, ensure that your toolchain is up to date. For the latest, run:
```bash
rustup update
```
Then, same as above, run `rustlings` to get started.
## Doing exercises
The exercises are sorted by topic and can be found in the subdirectory `rustlings/exercises/<topic>`. For every topic there is an additional README file with some resources to get you started on the topic. We really recommend that you have a look at them before you start.
The task is simple. Most exercises contain an error that keeps them from compiling, and it's up to you to fix it! Some exercises are also run as tests, but rustlings handles them all the same. To run the exercises in the recommended order, execute:
```bash
rustlings watch
```
This will try to verify the completion of every exercise in a predetermined order (what we think is best for newcomers). It will also rerun automatically every time you change a file in the `exercises/` directory. If you want to only run it once, you can use:
```bash
rustlings verify
```
This will do the same as watch, but it'll quit after running.
In case you want to go by your own order, or want to only verify a single exercise, you can run:
```bash
rustlings run myExercise1
```
Or simply use the following command to run the next unsolved exercise in the course:
```bash
rustlings run next
```
In case you get stuck, you can run the following command to get a hint for your
exercise:
```bash
rustlings hint myExercise1
```
You can also get the hint for the next unsolved exercise with the following command:
```bash
rustlings hint next
```
To check your progress, you can run the following command:
```bash
rustlings list
```
## Testing yourself
After every couple of sections, there will be a quiz that'll test your knowledge on a bunch of sections at once. These quizzes are found in `exercises/quizN.rs`.
## Enabling `rust-analyzer`
Run the command `rustlings lsp` which will generate a `rust-project.json` at the root of the project, this allows [rust-analyzer](https://rust-analyzer.github.io/) to parse each exercise.
## Continuing On
Once you've completed Rustlings, put your new knowledge to good use! Continue practicing your Rust skills by building your own projects, contributing to Rustlings, or finding other open-source projects to contribute to.
## Uninstalling Rustlings
If you want to remove Rustlings from your system, there are two steps. First, you'll need to remove the exercises folder that the install script created
for you:
```bash
rm -rf rustlings # or your custom folder name, if you chose and or renamed it
```
Second, run `cargo uninstall` to remove the `rustlings` binary:
```bash
cargo uninstall rustlings
```
Now you should be done!
## Contributing
See [CONTRIBUTING.md](https://github.com/rust-lang/rustlings/blob/main/CONTRIBUTING.md).
## Contributors ✨
Thanks goes to the wonderful people listed in [AUTHORS.md](https://github.com/rust-lang/rustlings/blob/main/AUTHORS.md) 🎉

View File

@ -13,7 +13,6 @@
// Execute `rustlings hint intro1` or use the `hint` watch subcommand for a // Execute `rustlings hint intro1` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
fn main() { fn main() {
println!("Hello and"); println!("Hello and");

View File

@ -5,8 +5,7 @@
// Execute `rustlings hint intro2` or use the `hint` watch subcommand for a // Execute `rustlings hint intro2` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
fn main() { fn main() {
printline!("Hello there!") let par: &str = "world";
println!("Hello {}!", par);
} }

View File

@ -5,9 +5,7 @@
// Execute `rustlings hint variables1` or use the `hint` watch subcommand for a // Execute `rustlings hint variables1` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
fn main() { fn main() {
x = 5; let x = 5;
println!("x has the value {}", x); println!("x has the value {}", x);
} }

View File

@ -3,10 +3,8 @@
// Execute `rustlings hint variables2` or use the `hint` watch subcommand for a // Execute `rustlings hint variables2` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
fn main() { fn main() {
let x; let x = 5;
if x == 10 { if x == 10 {
println!("x is ten!"); println!("x is ten!");
} else { } else {

View File

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

View File

@ -3,10 +3,9 @@
// Execute `rustlings hint variables4` or use the `hint` watch subcommand for a // Execute `rustlings hint variables4` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
fn main() { fn main() {
let x = 3; let mut x = 3;
println!("Number {}", x); println!("Number {}", x);
x = 5; // don't change this line x = 5; // don't change this line
println!("Number {}", x); println!("Number {}", x);

View File

@ -3,11 +3,9 @@
// Execute `rustlings hint variables5` or use the `hint` watch subcommand for a // Execute `rustlings hint variables5` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
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);
number = 3; // don't rename this variable let number = 3; // don't rename this variable
println!("Number plus two is : {}", number + 2); println!("Number plus two is : {}", number + 2);
} }

View File

@ -3,9 +3,7 @@
// Execute `rustlings hint variables6` or use the `hint` watch subcommand for a // Execute `rustlings hint variables6` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE const NUMBER :u8 = 3;
const NUMBER = 3;
fn main() { fn main() {
println!("Number {}", NUMBER); println!("Number {}", NUMBER);
} }

View File

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

View File

@ -3,13 +3,11 @@
// Execute `rustlings hint functions2` or use the `hint` watch subcommand for a // Execute `rustlings hint functions2` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
fn main() { fn main() {
call_me(3); call_me(3);
} }
fn call_me(num:) { fn call_me(num: i32) {
for i in 0..num { for i in 0..num {
println!("Ring! Call number {}", i + 1); println!("Ring! Call number {}", i + 1);
} }

View File

@ -3,10 +3,9 @@
// Execute `rustlings hint functions3` or use the `hint` watch subcommand for a // Execute `rustlings hint functions3` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
fn main() { fn main() {
call_me(); call_me(1000);
} }
fn call_me(num: u32) { fn call_me(num: u32) {

View File

@ -8,14 +8,13 @@
// Execute `rustlings hint functions4` or use the `hint` watch subcommand for a // Execute `rustlings hint functions4` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
fn main() { fn main() {
let original_price = 51; let original_price = 51;
println!("Your sale price is {}", sale_price(original_price)); println!("Your sale price is {}", sale_price(original_price));
} }
fn sale_price(price: i32) -> { fn sale_price(price: u32) -> u32 {
if is_even(price) { if is_even(price) {
price - 10 price - 10
} else { } else {
@ -23,6 +22,6 @@ fn sale_price(price: i32) -> {
} }
} }
fn is_even(num: i32) -> bool { fn is_even(num: u32) -> bool {
num % 2 == 0 num % 2 == 0
} }

View File

@ -3,7 +3,6 @@
// Execute `rustlings hint functions5` or use the `hint` watch subcommand for a // Execute `rustlings hint functions5` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
fn main() { fn main() {
let answer = square(3); let answer = square(3);
@ -11,5 +10,5 @@ fn main() {
} }
fn square(num: i32) -> i32 { fn square(num: i32) -> i32 {
num * num; num * num
} }

View File

@ -2,13 +2,16 @@
// //
// Execute `rustlings hint if1` or use the `hint` watch subcommand for a hint. // Execute `rustlings hint if1` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE
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!
// Do not use: // Do not use:
// - another function call // - another function call
// - additional variables // - additional variables
if a > b {
return a;
}
b
} }
// Don't mind this for now :) // Don't mind this for now :)

View File

@ -5,13 +5,14 @@
// //
// Execute `rustlings hint if2` or use the `hint` watch subcommand for a hint. // Execute `rustlings hint if2` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE
pub fn foo_if_fizz(fizzish: &str) -> &str { pub fn foo_if_fizz(fizzish: &str) -> &str {
if fizzish == "fizz" { if fizzish == "fizz" {
"foo" "foo"
} else if fizzish == "fuzz" {
"bar"
} else { } else {
1 "baz"
} }
} }

View File

@ -2,17 +2,16 @@
// //
// Execute `rustlings hint if3` or use the `hint` watch subcommand for a hint. // Execute `rustlings hint if3` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE
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
} else if animal == "gopher" { } else if animal == "gopher" {
2.0 2
} else if animal == "snake" { } else if animal == "snake" {
3 3
} else { } else {
"Unknown" 0
}; };
// DO NOT CHANGE THIS STATEMENT BELOW // DO NOT CHANGE THIS STATEMENT BELOW

View File

@ -3,7 +3,6 @@
// Fill in the rest of the line that has code missing! No hints, there's no // Fill in the rest of the line that has code missing! No hints, there's no
// tricks, just get used to typing these :) // tricks, just get used to typing these :)
// I AM NOT DONE
fn main() { fn main() {
// Booleans (`bool`) // Booleans (`bool`)
@ -13,7 +12,7 @@ fn main() {
println!("Good morning!"); println!("Good morning!");
} }
let // Finish the rest of this line like the example! Or make it be false! let is_evening = true; // Finish the rest of this line like the example! Or make it be false!
if is_evening { if is_evening {
println!("Good evening!"); println!("Good evening!");
} }

View File

@ -3,7 +3,6 @@
// Fill in the rest of the line that has code missing! No hints, there's no // Fill in the rest of the line that has code missing! No hints, there's no
// tricks, just get used to typing these :) // tricks, just get used to typing these :)
// I AM NOT DONE
fn main() { fn main() {
// Characters (`char`) // Characters (`char`)
@ -19,7 +18,7 @@ fn main() {
println!("Neither alphabetic nor numeric!"); println!("Neither alphabetic nor numeric!");
} }
let // Finish this line like the example! What's your favorite character? let your_character = '1'; // Finish this line like the example! What's your favorite character?
// Try a letter, try a number, try a special character, try a character // Try a letter, try a number, try a special character, try a character
// from a different language than your own, try an emoji! // from a different language than your own, try an emoji!
if your_character.is_alphabetic() { if your_character.is_alphabetic() {

View File

@ -5,10 +5,9 @@
// Execute `rustlings hint primitive_types3` or use the `hint` watch subcommand // Execute `rustlings hint primitive_types3` or use the `hint` watch subcommand
// for a hint. // for a hint.
// I AM NOT DONE
fn main() { fn main() {
let a = ??? let a = [1;1000];
if a.len() >= 100 { if a.len() >= 100 {
println!("Wow, that's a big array!"); println!("Wow, that's a big array!");

View File

@ -5,13 +5,12 @@
// Execute `rustlings hint primitive_types4` or use the `hint` watch subcommand // Execute `rustlings hint primitive_types4` or use the `hint` watch subcommand
// for a hint. // for a hint.
// I AM NOT DONE
#[test] #[test]
fn slice_out_of_array() { fn slice_out_of_array() {
let a = [1, 2, 3, 4, 5]; let a = [1, 2, 3, 4, 5];
let nice_slice = ??? let nice_slice = &a[1..4];
assert_eq!([2, 3, 4], nice_slice) assert_eq!([2, 3, 4], nice_slice)
} }

View File

@ -5,11 +5,10 @@
// Execute `rustlings hint primitive_types5` or use the `hint` watch subcommand // Execute `rustlings hint primitive_types5` or use the `hint` watch subcommand
// for a hint. // for a hint.
// I AM NOT DONE
fn main() { fn main() {
let cat = ("Furry McFurson", 3.5); let cat = ("Furry McFurson", 3.5);
let /* your pattern here */ = cat; let (name,age) = cat;
println!("{} is {} years old.", name, age); println!("{} is {} years old.", name, age);
} }

View File

@ -6,13 +6,12 @@
// Execute `rustlings hint primitive_types6` or use the `hint` watch subcommand // Execute `rustlings hint primitive_types6` or use the `hint` watch subcommand
// for a hint. // for a hint.
// I AM NOT DONE
#[test] #[test]
fn indexing_tuple() { fn indexing_tuple() {
let numbers = (1, 2, 3); let numbers = (1, 2, 3);
// Replace below ??? with the tuple indexing syntax. // Replace below ??? with the tuple indexing syntax.
let second = ???; let second = numbers.1;
assert_eq!(2, second, assert_eq!(2, second,
"This is not the 2nd number in the tuple!") "This is not the 2nd number in the tuple!")

View File

@ -7,11 +7,10 @@
// //
// Execute `rustlings hint vecs1` or use the `hint` watch subcommand for a hint. // Execute `rustlings hint vecs1` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE
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
let v = // TODO: declare your vector here with the macro for vectors let v = vec![a[0],a[1],a[2],a[3]]; // TODO: declare your vector here with the macro for vectors
(a, v) (a, v)
} }

View File

@ -7,13 +7,11 @@
// //
// Execute `rustlings hint vecs2` or use the `hint` watch subcommand for a hint. // Execute `rustlings hint vecs2` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE
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() {
// TODO: Fill this up so that each element in the Vec `v` is // TODO: Fill this up so that each element in the Vec `v` is
// multiplied by 2. // multiplied by 2.
??? *element *= 2;
} }
// At this point, `v` should be equal to [4, 8, 12, 16, 20]. // At this point, `v` should be equal to [4, 8, 12, 16, 20].
@ -21,11 +19,13 @@ fn vec_loop(mut v: Vec<i32>) -> Vec<i32> {
} }
fn vec_map(v: &Vec<i32>) -> Vec<i32> { fn vec_map(v: &Vec<i32>) -> Vec<i32> {
v.iter().map(|element| { v.iter()
// TODO: Do the same thing as above - but instead of mutating the .map(|element| {
// Vec, you can just return the new number! // TODO: Do the same thing as above - but instead of mutating the
??? // Vec, you can just return the new number!
}).collect() element * 2
})
.collect()
} }
#[cfg(test)] #[cfg(test)]

View File

@ -3,7 +3,6 @@
// Execute `rustlings hint move_semantics1` or use the `hint` watch subcommand // Execute `rustlings hint move_semantics1` or use the `hint` watch subcommand
// for a hint. // for a hint.
// I AM NOT DONE
#[test] #[test]
fn main() { fn main() {
@ -15,7 +14,7 @@ fn main() {
} }
fn fill_vec(vec: Vec<i32>) -> Vec<i32> { fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
let vec = vec; let mut vec = vec;
vec.push(88); vec.push(88);

View File

@ -5,20 +5,18 @@
// Execute `rustlings hint move_semantics2` or use the `hint` watch subcommand // Execute `rustlings hint move_semantics2` or use the `hint` watch subcommand
// for a hint. // for a hint.
// I AM NOT DONE
#[test] #[test]
fn main() { fn main() {
let vec0 = vec![22, 44, 66]; let vec0 = vec![22, 44, 66];
let mut vec1 = fill_vec(vec0); let mut vec1 = fill_vec(&vec0);
assert_eq!(vec0, vec![22, 44, 66]); assert_eq!(vec0, vec![22, 44, 66]);
assert_eq!(vec1, vec![22, 44, 66, 88]); 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.clone();
vec.push(88); vec.push(88);

View File

@ -6,18 +6,16 @@
// Execute `rustlings hint move_semantics3` or use the `hint` watch subcommand // Execute `rustlings hint move_semantics3` or use the `hint` watch subcommand
// for a hint. // for a hint.
// I AM NOT DONE
#[test] #[test]
fn main() { fn main() {
let vec0 = vec![22, 44, 66]; let vec0 = vec![22, 44, 66];
let mut vec1 = fill_vec(vec0); let vec1 = fill_vec(vec0);
assert_eq!(vec1, vec![22, 44, 66, 88]); assert_eq!(vec1, vec![22, 44, 66, 88]);
} }
fn fill_vec(vec: Vec<i32>) -> Vec<i32> { fn fill_vec(mut vec: Vec<i32>) -> Vec<i32> {
vec.push(88); vec.push(88);
vec vec

View File

@ -7,21 +7,17 @@
// Execute `rustlings hint move_semantics4` or use the `hint` watch subcommand // Execute `rustlings hint move_semantics4` or use the `hint` watch subcommand
// for a hint. // for a hint.
// I AM NOT DONE
#[test] #[test]
fn main() { fn main() {
let vec0 = vec![22, 44, 66]; let vec1 = fill_vec();
let mut vec1 = fill_vec(vec0);
assert_eq!(vec1, vec![22, 44, 66, 88]); 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> {
let mut vec = vec![22, 44, 66];
// Instead, let's create and fill the Vec in here - how do you do that? // Instead, let's create and fill the Vec in here - how do you do that?
let mut vec = vec;
vec.push(88); vec.push(88);

View File

@ -6,14 +6,12 @@
// Execute `rustlings hint move_semantics5` or use the `hint` watch subcommand // Execute `rustlings hint move_semantics5` or use the `hint` watch subcommand
// for a hint. // for a hint.
// I AM NOT DONE
#[test] #[test]
fn main() { fn main() {
let mut x = 100; let mut x = 100;
let y = &mut x; let y = &mut x;
let z = &mut x;
*y += 100; *y += 100;
let z = &mut x;
*z += 1000; *z += 1000;
assert_eq!(x, 1200); assert_eq!(x, 1200);
} }

View File

@ -5,24 +5,23 @@
// Execute `rustlings hint move_semantics6` or use the `hint` watch subcommand // Execute `rustlings hint move_semantics6` or use the `hint` watch subcommand
// for a hint. // for a hint.
// I AM NOT DONE
fn main() { fn main() {
let data = "Rust is great!".to_string(); let data = "Rust is great!".to_string();
get_char(data); let letter = get_char(&data);
println!("Letter is {}", letter);
string_uppercase(&data); string_uppercase(data);
} }
// Should not take ownership // Should not take ownership
fn get_char(data: String) -> char { fn get_char(data: &String) -> char {
data.chars().last().unwrap() data.chars().last().unwrap()
} }
// Should take ownership // Should take ownership
fn string_uppercase(mut data: &String) { fn string_uppercase(mut data: String) {
data = &data.to_uppercase(); data = data.to_uppercase();
println!("{}", data); println!("{}", data);
} }

View File

@ -5,13 +5,13 @@
// Execute `rustlings hint structs1` or use the `hint` watch subcommand for a // Execute `rustlings hint structs1` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
struct ColorClassicStruct { struct ColorClassicStruct {
// TODO: Something goes here red: u8,
green: u8,
blue: u8,
} }
struct ColorTupleStruct(/* TODO: Something goes here */); struct ColorTupleStruct(u8,u8,u8);
#[derive(Debug)] #[derive(Debug)]
struct UnitLikeStruct; struct UnitLikeStruct;
@ -23,7 +23,7 @@ mod tests {
#[test] #[test]
fn classic_c_structs() { fn classic_c_structs() {
// TODO: Instantiate a classic c struct! // TODO: Instantiate a classic c struct!
// let green = let green = ColorClassicStruct{red: 0, green: 255, blue: 0};
assert_eq!(green.red, 0); assert_eq!(green.red, 0);
assert_eq!(green.green, 255); assert_eq!(green.green, 255);
@ -33,7 +33,7 @@ mod tests {
#[test] #[test]
fn tuple_structs() { fn tuple_structs() {
// TODO: Instantiate a tuple struct! // TODO: Instantiate a tuple struct!
// let green = let green = (0,255,0);
assert_eq!(green.0, 0); assert_eq!(green.0, 0);
assert_eq!(green.1, 255); assert_eq!(green.1, 255);
@ -43,7 +43,7 @@ mod tests {
#[test] #[test]
fn unit_structs() { fn unit_structs() {
// TODO: Instantiate a unit-like struct! // TODO: Instantiate a unit-like struct!
// let unit_like_struct = let unit_like_struct = UnitLikeStruct;
let message = format!("{:?}s are fun!", unit_like_struct); let message = format!("{:?}s are fun!", unit_like_struct);
assert_eq!(message, "UnitLikeStructs are fun!"); assert_eq!(message, "UnitLikeStructs are fun!");

View File

@ -5,8 +5,6 @@
// Execute `rustlings hint structs2` or use the `hint` watch subcommand for a // Execute `rustlings hint structs2` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
#[derive(Debug)] #[derive(Debug)]
struct Order { struct Order {
name: String, name: String,
@ -38,7 +36,11 @@ mod tests {
fn your_order() { fn your_order() {
let order_template = create_order_template(); let order_template = create_order_template();
// TODO: Create your own order using the update syntax and template above! // TODO: Create your own order using the update syntax and template above!
// let your_order = let your_order = Order{
name: "Hacker in Rust".to_string(),
count: 1,
..order_template
};
assert_eq!(your_order.name, "Hacker in Rust"); assert_eq!(your_order.name, "Hacker in Rust");
assert_eq!(your_order.year, order_template.year); assert_eq!(your_order.year, order_template.year);
assert_eq!(your_order.made_by_phone, order_template.made_by_phone); assert_eq!(your_order.made_by_phone, order_template.made_by_phone);

View File

@ -7,7 +7,6 @@
// Execute `rustlings hint structs3` or use the `hint` watch subcommand for a // Execute `rustlings hint structs3` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
#[derive(Debug)] #[derive(Debug)]
struct Package { struct Package {
@ -31,12 +30,14 @@ impl Package {
} }
} }
fn is_international(&self) -> ??? { fn is_international(&self) -> bool {
// Something goes here... // Something goes here...
return self.sender_country != self.recipient_country;
} }
fn get_fees(&self, cents_per_gram: u32) -> ??? { fn get_fees(&self, cents_per_gram: u32) -> u32 {
// Something goes here... // Something goes here...
self.weight_in_grams * cents_per_gram
} }
} }

View File

@ -2,11 +2,14 @@
// //
// No hints this time! ;) // No hints this time! ;)
// I AM NOT DONE
#[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
Quit,
Echo,
Move,
ChangeColor,
} }
fn main() { fn main() {

View File

@ -3,11 +3,14 @@
// Execute `rustlings hint enums2` or use the `hint` watch subcommand for a // Execute `rustlings hint enums2` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
#[derive(Debug)] #[derive(Debug)]
enum Message { enum Message {
// TODO: define the different variants used below // TODO: define the different variants used below
Move { x: u8, y: u8 },
Echo(String),
ChangeColor(u8, u8, u8),
Quit,
} }
impl Message { impl Message {

View File

@ -5,10 +5,12 @@
// Execute `rustlings hint enums3` or use the `hint` watch subcommand for a // Execute `rustlings hint enums3` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
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
ChangeColor(u8, u8, u8),
Echo(String),
Move(Point),
Quit,
} }
struct Point { struct Point {
@ -44,6 +46,20 @@ impl State {
// TODO: create a match expression to process the different message variants // TODO: create a match expression to process the different message variants
// Remember: When passing a tuple as a function argument, you'll need extra parentheses: // Remember: When passing a tuple as a function argument, you'll need extra parentheses:
// fn function((t, u, p, l, e)) // fn function((t, u, p, l, e))
match message {
Message::ChangeColor(r, g, b) => {
self.color = (r, g, b);
}
Message::Echo(m) => {
self.message = m;
}
Message::Move(Point { x, y }) => {
self.position = Point { x, y };
}
Message::Quit => {
self.quit = true;
}
}
} }
} }

View File

@ -5,7 +5,6 @@
// Execute `rustlings hint strings1` or use the `hint` watch subcommand for a // Execute `rustlings hint strings1` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
fn main() { fn main() {
let answer = current_favorite_color(); let answer = current_favorite_color();
@ -13,5 +12,5 @@ fn main() {
} }
fn current_favorite_color() -> String { fn current_favorite_color() -> String {
"blue" "blue".to_string()
} }

View File

@ -5,11 +5,9 @@
// Execute `rustlings hint strings2` or use the `hint` watch subcommand for a // Execute `rustlings hint strings2` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
fn main() { fn main() {
let word = String::from("green"); // Try not changing this line :) let word = String::from("green"); // Try not changing this line :)
if is_a_color_word(word) { if is_a_color_word(&word) {
println!("That is a color word I know!"); println!("That is a color word I know!");
} else { } else {
println!("That is not a color word I know."); println!("That is not a color word I know.");

View File

@ -3,21 +3,21 @@
// Execute `rustlings hint strings3` or use the `hint` watch subcommand for a // Execute `rustlings hint strings3` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
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!
??? input.trim().to_string()
} }
fn compose_me(input: &str) -> String { fn compose_me(input: &str) -> String {
// TODO: Add " world!" to the string! There's multiple ways to do this! // TODO: Add " world!" to the string! There's multiple ways to do this!
??? let return_string = input.to_string() + " world!";
return_string
} }
fn replace_me(input: &str) -> String { fn replace_me(input: &str) -> String {
// TODO: Replace "cars" in the string with "balloons"! // TODO: Replace "cars" in the string with "balloons"!
??? input.replace("cars", "balloons")
} }
#[cfg(test)] #[cfg(test)]

View File

@ -7,7 +7,6 @@
// //
// No hints this time! // No hints this time!
// I AM NOT DONE
fn string_slice(arg: &str) { fn string_slice(arg: &str) {
println!("{}", arg); println!("{}", arg);
@ -17,14 +16,14 @@ fn string(arg: String) {
} }
fn main() { fn main() {
???("blue"); string_slice("blue");
???("red".to_string()); string("red".to_string());
???(String::from("hi")); string(String::from("hi"));
???("rust is fun!".to_owned()); string("rust is fun!".to_owned());
???("nice weather".into()); string_slice("nice weather".into());
???(format!("Interpolation {}", "Station")); string(format!("Interpolation {}", "Station"));
???(&String::from("abc")[0..1]); string_slice(&String::from("abc")[0..1]);
???(" hello there ".trim()); string_slice(" hello there ".trim());
???("Happy Monday!".to_string().replace("Mon", "Tues")); string("Happy Monday!".to_string().replace("Mon", "Tues"));
???("mY sHiFt KeY iS sTiCkY".to_lowercase()); string("mY sHiFt KeY iS sTiCkY".to_lowercase());
} }

View File

@ -3,7 +3,6 @@
// Execute `rustlings hint modules1` or use the `hint` watch subcommand for a // Execute `rustlings hint modules1` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
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!
@ -11,7 +10,7 @@ mod sausage_factory {
String::from("Ginger") String::from("Ginger")
} }
fn make_sausage() { pub fn make_sausage() {
get_secret_recipe(); get_secret_recipe();
println!("sausage!"); println!("sausage!");
} }

View File

@ -7,12 +7,11 @@
// Execute `rustlings hint modules2` or use the `hint` watch subcommand for a // Execute `rustlings hint modules2` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
mod delicious_snacks { mod delicious_snacks {
// TODO: Fix these use statements // TODO: Fix these use statements
use self::fruits::PEAR as ??? pub use self::fruits::PEAR as fruit;
use self::veggies::CUCUMBER as ??? pub use self::veggies::CUCUMBER as veggie;
mod fruits { mod fruits {
pub const PEAR: &'static str = "Pear"; pub const PEAR: &'static str = "Pear";

View File

@ -8,10 +8,9 @@
// Execute `rustlings hint modules3` or use the `hint` watch subcommand for a // Execute `rustlings hint modules3` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
// TODO: Complete this use statement // TODO: Complete this use statement
use ??? use std::time::*;
fn main() { fn main() {
match SystemTime::now().duration_since(UNIX_EPOCH) { match SystemTime::now().duration_since(UNIX_EPOCH) {

View File

@ -11,17 +11,17 @@
// Execute `rustlings hint hashmaps1` or use the `hint` watch subcommand for a // Execute `rustlings hint hashmaps1` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
use std::collections::HashMap; use std::collections::HashMap;
fn fruit_basket() -> HashMap<String, u32> { fn fruit_basket() -> HashMap<String, u32> {
let mut basket = // TODO: declare your hash map here. let mut basket = HashMap::new();
// Two bananas are already given for you :) // Two bananas are already given for you :)
basket.insert(String::from("banana"), 2); basket.insert(String::from("banana"), 2);
// TODO: Put more fruits in your basket here. // TODO: Put more fruits in your basket here.
basket.insert(String::from("apple"), 3);
basket.insert(String::from("cherry"), 1);
basket basket
} }

View File

@ -14,7 +14,6 @@
// Execute `rustlings hint hashmaps2` or use the `hint` watch subcommand for a // Execute `rustlings hint hashmaps2` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
use std::collections::HashMap; use std::collections::HashMap;
@ -40,6 +39,7 @@ fn fruit_basket(basket: &mut HashMap<Fruit, u32>) {
// TODO: Insert new fruits if they are not already present in the // 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 // basket. Note that you are not allowed to put any type of fruit that's
// already present! // already present!
basket.entry(fruit).or_insert(1);
} }
} }
@ -81,7 +81,7 @@ mod tests {
let count = basket.values().sum::<u32>(); let count = basket.values().sum::<u32>();
assert!(count > 11); assert!(count > 11);
} }
#[test] #[test]
fn all_fruit_types_in_basket() { fn all_fruit_types_in_basket() {
let mut basket = get_fruit_basket(); let mut basket = get_fruit_basket();

View File

@ -14,8 +14,6 @@
// Execute `rustlings hint hashmaps3` or use the `hint` watch subcommand for a // Execute `rustlings hint hashmaps3` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
use std::collections::HashMap; use std::collections::HashMap;
// A structure to store the goal details of a team. // A structure to store the goal details of a team.
@ -39,6 +37,22 @@ fn build_scores_table(results: String) -> HashMap<String, Team> {
// will be the number of goals conceded by team_2, and similarly // will be the number of goals conceded by team_2, and similarly
// goals scored by team_2 will be the number of goals conceded by // goals scored by team_2 will be the number of goals conceded by
// team_1. // team_1.
let team_1 = scores.entry(team_1_name).or_insert(Team {
goals_scored: 0,
goals_conceded: 0,
});
(*team_1).goals_conceded += team_2_score;
(*team_1).goals_scored += team_1_score;
let team_2 = scores.entry(team_2_name).or_insert(Team {
goals_scored: 0,
goals_conceded: 0,
});
(*team_2).goals_conceded += team_1_score;
(*team_2).goals_scored += team_2_score;
} }
scores scores
} }

View File

@ -3,8 +3,6 @@
// Execute `rustlings hint options1` or use the `hint` watch subcommand for a // Execute `rustlings hint options1` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
// 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 pieces left. At 10PM, someone eats them // If it's before 10PM, there's 5 pieces left. At 10PM, someone eats them
// all, so there'll be no more left :( // all, so there'll be no more left :(
@ -13,7 +11,13 @@ fn maybe_icecream(time_of_day: u16) -> Option<u16> {
// value of 0 The Option output should gracefully handle cases where // value of 0 The Option output should gracefully handle cases where
// time_of_day > 23. // time_of_day > 23.
// TODO: Complete the function body - remember to return an Option! // TODO: Complete the function body - remember to return an Option!
??? if time_of_day > 23 {
return None;
}
if time_of_day > 21 {
return Some(0);
}
Some(5)
} }
#[cfg(test)] #[cfg(test)]
@ -33,7 +37,7 @@ mod tests {
fn raw_value() { fn raw_value() {
// TODO: Fix this test. How do you get at the value contained in the // TODO: Fix this test. How do you get at the value contained in the
// Option? // Option?
let icecreams = maybe_icecream(12); let icecreams = maybe_icecream(12).unwrap_or(0);
assert_eq!(icecreams, 5); assert_eq!(icecreams, 5);
} }
} }

View File

@ -3,8 +3,6 @@
// Execute `rustlings hint options2` or use the `hint` watch subcommand for a // Execute `rustlings hint options2` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
#[test] #[test]
@ -13,7 +11,7 @@ mod tests {
let optional_target = Some(target); let optional_target = Some(target);
// TODO: Make this an if let statement whose value is "Some" type // TODO: Make this an if let statement whose value is "Some" type
word = optional_target { if let Some(word) = optional_target {
assert_eq!(word, target); assert_eq!(word, target);
} }
} }
@ -32,7 +30,8 @@ mod tests {
// TODO: make this a while let statement - remember that vector.pop also // TODO: make this a while let statement - remember that vector.pop also
// adds another layer of Option<T>. You can stack `Option<T>`s into // adds another layer of Option<T>. You can stack `Option<T>`s into
// while let and if let. // while let and if let.
integer = optional_integers.pop() { while let Some(Some(integer)) = optional_integers.pop() {
println!("resulting integer: {}", integer);
assert_eq!(integer, cursor); assert_eq!(integer, cursor);
cursor -= 1; cursor -= 1;
} }

View File

@ -3,8 +3,6 @@
// Execute `rustlings hint options3` or use the `hint` watch subcommand for a // Execute `rustlings hint options3` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
struct Point { struct Point {
x: i32, x: i32,
y: i32, y: i32,
@ -14,7 +12,7 @@ fn main() {
let y: Option<Point> = Some(Point { x: 100, y: 200 }); let y: Option<Point> = Some(Point { x: 100, y: 200 });
match y { match y {
Some(p) => println!("Co-ordinates are {},{} ", p.x, p.y), Some(ref p) => println!("Co-ordinates are {},{} ", p.x, p.y),
_ => panic!("no match!"), _ => panic!("no match!"),
} }
y; // Fix without deleting this line. y; // Fix without deleting this line.

View File

@ -9,14 +9,12 @@
// Execute `rustlings hint errors1` or use the `hint` watch subcommand for a // Execute `rustlings hint errors1` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE pub fn generate_nametag_text(name: String) -> Result<String, String> {
pub fn generate_nametag_text(name: String) -> Option<String> {
if name.is_empty() { if name.is_empty() {
// Empty names aren't allowed. // Empty names aren't allowed.
None Err("`name` was empty; it must be nonempty.".into())
} else { } else {
Some(format!("Hi! My name is {}", name)) Ok(format!("Hi! My name is {}", name))
} }
} }

View File

@ -19,15 +19,12 @@
// Execute `rustlings hint errors2` or use the `hint` watch subcommand for a // Execute `rustlings hint errors2` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
use std::num::ParseIntError; use std::num::ParseIntError;
pub fn total_cost(item_quantity: &str) -> Result<i32, ParseIntError> { pub fn total_cost(item_quantity: &str) -> Result<i32, ParseIntError> {
let processing_fee = 1; let processing_fee = 1;
let cost_per_item = 5; let cost_per_item = 5;
let qty = item_quantity.parse::<i32>(); let qty = item_quantity.parse::<i32>()?;
Ok(qty * cost_per_item + processing_fee) Ok(qty * cost_per_item + processing_fee)
} }

View File

@ -7,11 +7,9 @@
// Execute `rustlings hint errors3` or use the `hint` watch subcommand for a // Execute `rustlings hint errors3` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
use std::num::ParseIntError; use std::num::ParseIntError;
fn main() { fn main() -> Result<(), ParseIntError> {
let mut tokens = 100; let mut tokens = 100;
let pretend_user_input = "8"; let pretend_user_input = "8";
@ -23,6 +21,7 @@ fn main() {
tokens -= cost; tokens -= cost;
println!("You now have {} tokens.", tokens); println!("You now have {} tokens.", tokens);
} }
Ok(())
} }
pub fn total_cost(item_quantity: &str) -> Result<i32, ParseIntError> { pub fn total_cost(item_quantity: &str) -> Result<i32, ParseIntError> {

View File

@ -3,8 +3,6 @@
// Execute `rustlings hint errors4` or use the `hint` watch subcommand for a // Execute `rustlings hint errors4` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
#[derive(PartialEq, Debug)] #[derive(PartialEq, Debug)]
struct PositiveNonzeroInteger(u64); struct PositiveNonzeroInteger(u64);
@ -16,7 +14,13 @@ enum CreationError {
impl PositiveNonzeroInteger { impl PositiveNonzeroInteger {
fn new(value: i64) -> Result<PositiveNonzeroInteger, CreationError> { fn new(value: i64) -> Result<PositiveNonzeroInteger, CreationError> {
// Hmm... Why is this always returning an Ok value? if value < 0 {
return Err(CreationError::Negative);
}
if value == 0 {
return Err(CreationError::Zero);
}
Ok(PositiveNonzeroInteger(value as u64)) Ok(PositiveNonzeroInteger(value as u64))
} }
} }

View File

@ -22,14 +22,12 @@
// Execute `rustlings hint errors5` or use the `hint` watch subcommand for a // Execute `rustlings hint errors5` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
use std::error; use std::error;
use std::fmt; use std::fmt;
use std::num::ParseIntError; use std::num::ParseIntError;
// TODO: update the return type of `main()` to make this compile. // TODO: update the return type of `main()` to make this compile.
fn main() -> Result<(), Box<dyn ???>> { fn main() -> Result<(), Box<dyn error::Error>> {
let pretend_user_input = "42"; let pretend_user_input = "42";
let x: i64 = pretend_user_input.parse()?; let x: i64 = pretend_user_input.parse()?;
println!("output={:?}", PositiveNonzeroInteger::new(x)?); println!("output={:?}", PositiveNonzeroInteger::new(x)?);

View File

@ -9,8 +9,6 @@
// Execute `rustlings hint errors6` or use the `hint` watch subcommand for a // Execute `rustlings hint errors6` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
use std::num::ParseIntError; use std::num::ParseIntError;
// This is a custom error type that we will be using in `parse_pos_nonzero()`. // This is a custom error type that we will be using in `parse_pos_nonzero()`.
@ -25,13 +23,17 @@ impl ParsePosNonzeroError {
ParsePosNonzeroError::Creation(err) ParsePosNonzeroError::Creation(err)
} }
// TODO: add another error conversion function here. // TODO: add another error conversion function here.
// fn from_parseint... fn from_parseint(err: ParseIntError) -> ParsePosNonzeroError {
ParsePosNonzeroError::ParseInt(err)
}
} }
fn parse_pos_nonzero(s: &str) -> Result<PositiveNonzeroInteger, ParsePosNonzeroError> { fn parse_pos_nonzero(s: &str) -> Result<PositiveNonzeroInteger, ParsePosNonzeroError> {
// TODO: change this to return an appropriate error instead of panicking // TODO: change this to return an appropriate error instead of panicking
// when `parse()` returns an error. // when `parse()` returns an error.
let x: i64 = s.parse().unwrap(); let x_opt = s.parse();
let x = x_opt.map_err(ParsePosNonzeroError::from_parseint)?;
PositiveNonzeroInteger::new(x).map_err(ParsePosNonzeroError::from_creation) PositiveNonzeroInteger::new(x).map_err(ParsePosNonzeroError::from_creation)
} }

View File

@ -6,9 +6,7 @@
// Execute `rustlings hint generics1` or use the `hint` watch subcommand for a // Execute `rustlings hint generics1` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
fn main() { fn main() {
let mut shopping_list: Vec<?> = Vec::new(); let mut shopping_list: Vec<&str> = Vec::new();
shopping_list.push("milk"); shopping_list.push("milk");
} }

View File

@ -6,14 +6,12 @@
// Execute `rustlings hint generics2` or use the `hint` watch subcommand for a // Execute `rustlings hint generics2` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE struct Wrapper<T> {
value: T,
struct Wrapper {
value: u32,
} }
impl Wrapper { impl<T> Wrapper<T> {
pub fn new(value: u32) -> Self { pub fn new(value: T) -> Self {
Wrapper { value } Wrapper { value }
} }
} }

View File

@ -7,14 +7,14 @@
// Execute `rustlings hint traits1` or use the `hint` watch subcommand for a // Execute `rustlings hint traits1` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
trait AppendBar { trait AppendBar {
fn append_bar(self) -> Self; fn append_bar(self) -> Self;
} }
impl AppendBar for String { impl AppendBar for String {
// TODO: Implement `AppendBar` for type `String`. fn append_bar(self) -> Self {
self + "Bar"
}
} }
fn main() { fn main() {

View File

@ -8,13 +8,17 @@
// //
// Execute `rustlings hint traits2` or use the `hint` watch subcommand for a hint. // Execute `rustlings hint traits2` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE
trait AppendBar { trait AppendBar {
fn append_bar(self) -> Self; fn append_bar(self) -> Self;
} }
// TODO: Implement trait `AppendBar` for a vector of strings. // TODO: Implement trait `AppendBar` for a vector of strings.
impl AppendBar for Vec<String> {
fn append_bar(mut self) -> Self {
self.push(String::from("Bar"));
self
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {

View File

@ -8,10 +8,10 @@
// Execute `rustlings hint traits3` or use the `hint` watch subcommand for a // Execute `rustlings hint traits3` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
pub trait Licensed { pub trait Licensed {
fn licensing_info(&self) -> String; fn licensing_info(&self) -> String {
return String::from("Some information");
}
} }
struct SomeSoftware { struct SomeSoftware {

View File

@ -7,8 +7,6 @@
// Execute `rustlings hint traits4` or use the `hint` watch subcommand for a // Execute `rustlings hint traits4` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
pub trait Licensed { pub trait Licensed {
fn licensing_info(&self) -> String { fn licensing_info(&self) -> String {
"some information".to_string() "some information".to_string()
@ -23,7 +21,7 @@ impl Licensed for SomeSoftware {}
impl Licensed for OtherSoftware {} impl Licensed for OtherSoftware {}
// YOU MAY ONLY CHANGE THE NEXT LINE // YOU MAY ONLY CHANGE THE NEXT LINE
fn compare_license_types(software: ??, software_two: ??) -> bool { fn compare_license_types(software: impl Licensed, software_two: impl Licensed) -> bool {
software.licensing_info() == software_two.licensing_info() software.licensing_info() == software_two.licensing_info()
} }

View File

@ -7,8 +7,6 @@
// Execute `rustlings hint traits5` or use the `hint` watch subcommand for a // Execute `rustlings hint traits5` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
pub trait SomeTrait { pub trait SomeTrait {
fn some_function(&self) -> bool { fn some_function(&self) -> bool {
true true
@ -30,7 +28,7 @@ impl SomeTrait for OtherStruct {}
impl OtherTrait for OtherStruct {} impl OtherTrait for OtherStruct {}
// YOU MAY ONLY CHANGE THE NEXT LINE // YOU MAY ONLY CHANGE THE NEXT LINE
fn some_func(item: ??) -> bool { fn some_func(item: impl SomeTrait + OtherTrait) -> bool {
item.some_function() && item.other_function() item.some_function() && item.other_function()
} }

View File

@ -8,9 +8,7 @@
// Execute `rustlings hint lifetimes1` or use the `hint` watch subcommand for a // Execute `rustlings hint lifetimes1` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
fn longest(x: &str, y: &str) -> &str {
if x.len() > y.len() { if x.len() > y.len() {
x x
} else { } else {

View File

@ -6,8 +6,6 @@
// Execute `rustlings hint lifetimes2` or use the `hint` watch subcommand for a // Execute `rustlings hint lifetimes2` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
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() {
x x
@ -18,9 +16,9 @@ fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
fn main() { fn main() {
let string1 = String::from("long string is long"); let string1 = String::from("long string is long");
let string2 = String::from("xyz");
let result; let result;
{ {
let string2 = String::from("xyz");
result = longest(string1.as_str(), string2.as_str()); result = longest(string1.as_str(), string2.as_str());
} }
println!("The longest string is '{}'", result); println!("The longest string is '{}'", result);

View File

@ -5,17 +5,18 @@
// Execute `rustlings hint lifetimes3` or use the `hint` watch subcommand for a // Execute `rustlings hint lifetimes3` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE struct Book<'a> {
author: &'a str,
struct Book { title: &'a str,
author: &str,
title: &str,
} }
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);
} }

View File

@ -10,12 +10,10 @@
// Execute `rustlings hint tests1` or use the `hint` watch subcommand for a // Execute `rustlings hint tests1` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
#[test] #[test]
fn you_can_assert() { fn you_can_assert() {
assert!(); assert!(1 == 1);
} }
} }

View File

@ -6,12 +6,10 @@
// Execute `rustlings hint tests2` or use the `hint` watch subcommand for a // Execute `rustlings hint tests2` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
#[test] #[test]
fn you_can_assert_eq() { fn you_can_assert_eq() {
assert_eq!(); assert_eq!("foo", "foo");
} }
} }

View File

@ -7,8 +7,6 @@
// Execute `rustlings hint tests3` or use the `hint` watch subcommand for a // Execute `rustlings hint tests3` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
pub fn is_even(num: i32) -> bool { pub fn is_even(num: i32) -> bool {
num % 2 == 0 num % 2 == 0
} }
@ -19,11 +17,11 @@ mod tests {
#[test] #[test]
fn is_true_when_even() { fn is_true_when_even() {
assert!(); assert!(is_even(2));
} }
#[test] #[test]
fn is_false_when_odd() { fn is_false_when_odd() {
assert!(); assert!(!is_even(5));
} }
} }

View File

@ -5,11 +5,9 @@
// Execute `rustlings hint tests4` or use the `hint` watch subcommand for a // Execute `rustlings hint tests4` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
struct Rectangle { struct Rectangle {
width: i32, width: i32,
height: i32 height: i32,
} }
impl Rectangle { impl Rectangle {
@ -18,7 +16,7 @@ impl Rectangle {
if width <= 0 || height <= 0 { if width <= 0 || height <= 0 {
panic!("Rectangle width and height cannot be negative!") panic!("Rectangle width and height cannot be negative!")
} }
Rectangle {width, height} Rectangle { width, height }
} }
} }
@ -30,17 +28,19 @@ mod tests {
fn correct_width_and_height() { fn correct_width_and_height() {
// This test should check if the rectangle is the size that we pass into its constructor // This test should check if the rectangle is the size that we pass into its constructor
let rect = Rectangle::new(10, 20); let rect = Rectangle::new(10, 20);
assert_eq!(???, 10); // check width assert_eq!(rect.width, 10); // check width
assert_eq!(???, 20); // check height assert_eq!(rect.height, 20); // check height
} }
#[test] #[test]
#[should_panic]
fn negative_width() { fn negative_width() {
// This test should check if program panics when we try to create rectangle with negative width // This test should check if program panics when we try to create rectangle with negative width
let _rect = Rectangle::new(-10, 10); let _rect = Rectangle::new(-10, 10);
} }
#[test] #[test]
#[should_panic]
fn negative_height() { fn negative_height() {
// This test should check if program panics when we try to create rectangle with negative height // This test should check if program panics when we try to create rectangle with negative height
let _rect = Rectangle::new(10, -10); let _rect = Rectangle::new(10, -10);

View File

@ -9,18 +9,16 @@
// Execute `rustlings hint iterators1` or use the `hint` watch subcommand for a // Execute `rustlings hint iterators1` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
#[test] #[test]
fn main() { fn main() {
let my_fav_fruits = vec!["banana", "custard apple", "avocado", "peach", "raspberry"]; 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 = my_fav_fruits.iter(); // 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(), Some(&"custard apple")); // 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(), Some(&"peach")); // 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(), None); // TODO: Step 4
} }

View File

@ -6,8 +6,6 @@
// Execute `rustlings hint iterators2` or use the `hint` watch subcommand for a // Execute `rustlings hint iterators2` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
// Step 1. // Step 1.
// Complete the `capitalize_first` function. // Complete the `capitalize_first` function.
// "hello" -> "Hello" // "hello" -> "Hello"
@ -15,7 +13,7 @@ pub fn capitalize_first(input: &str) -> String {
let mut c = input.chars(); let mut c = input.chars();
match c.next() { match c.next() {
None => String::new(), None => String::new(),
Some(first) => ???, Some(first) => first.to_uppercase().to_string() + c.as_str(),
} }
} }
@ -24,7 +22,14 @@ pub fn capitalize_first(input: &str) -> String {
// Return a vector of strings. // Return a vector of strings.
// ["hello", "world"] -> ["Hello", "World"] // ["hello", "world"] -> ["Hello", "World"]
pub fn capitalize_words_vector(words: &[&str]) -> Vec<String> { pub fn capitalize_words_vector(words: &[&str]) -> Vec<String> {
vec![] let words_iter = words.iter();
let mut cap: Vec<String> = vec![];
for word in words_iter {
cap.push(capitalize_first(word));
}
cap
} }
// Step 3. // Step 3.
@ -32,7 +37,7 @@ pub fn capitalize_words_vector(words: &[&str]) -> Vec<String> {
// Return a single string. // Return a single string.
// ["hello", " ", "world"] -> "Hello World" // ["hello", " ", "world"] -> "Hello World"
pub fn capitalize_words_string(words: &[&str]) -> String { pub fn capitalize_words_string(words: &[&str]) -> String {
String::new() words.iter().map(|x| capitalize_first(x)).collect()
} }
#[cfg(test)] #[cfg(test)]

View File

@ -9,8 +9,6 @@
// Execute `rustlings hint iterators3` or use the `hint` watch subcommand for a // Execute `rustlings hint iterators3` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq)]
pub enum DivisionError { pub enum DivisionError {
NotDivisible(NotDivisibleError), NotDivisible(NotDivisibleError),
@ -26,23 +24,36 @@ pub struct NotDivisibleError {
// Calculate `a` divided by `b` if `a` is evenly divisible by `b`. // Calculate `a` divided by `b` if `a` is evenly divisible by `b`.
// Otherwise, return a suitable error. // Otherwise, return a suitable error.
pub fn divide(a: i32, b: i32) -> Result<i32, DivisionError> { pub fn divide(a: i32, b: i32) -> Result<i32, DivisionError> {
todo!(); if b == 0 {
return Err(DivisionError::DivideByZero);
}
if a % b != 0 {
return Err(DivisionError::NotDivisible(NotDivisibleError {
dividend: a,
divisor: b,
}));
}
Ok(a / b)
} }
// Complete the function and return a value of the correct type so the test // Complete the function and return a value of the correct type so the test
// passes. // passes.
// Desired output: Ok([1, 11, 1426, 3]) // Desired output: Ok([1, 11, 1426, 3])
fn result_with_list() -> () { fn result_with_list() -> Result<Vec<i32>, DivisionError> {
let numbers = vec![27, 297, 38502, 81]; let numbers = vec![27, 297, 38502, 81];
let division_results = numbers.into_iter().map(|n| divide(n, 27)); let division_results = numbers.into_iter().map(|n| divide(n, 27));
division_results.collect()
} }
// Complete the function and return a value of the correct type so the test // Complete the function and return a value of the correct type so the test
// passes. // passes.
// Desired output: [Ok(1), Ok(11), Ok(1426), Ok(3)] // Desired output: [Ok(1), Ok(11), Ok(1426), Ok(3)]
fn list_of_results() -> () { fn list_of_results() -> Vec<Result<i32, DivisionError>> {
let numbers = vec![27, 297, 38502, 81]; let numbers = vec![27, 297, 38502, 81];
let division_results = numbers.into_iter().map(|n| divide(n, 27)); let division_results = numbers.into_iter().map(|n| divide(n, 27));
division_results.collect()
} }
#[cfg(test)] #[cfg(test)]

View File

@ -3,8 +3,6 @@
// Execute `rustlings hint iterators4` or use the `hint` watch subcommand for a // Execute `rustlings hint iterators4` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
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:
@ -15,6 +13,12 @@ pub fn factorial(num: u64) -> u64 {
// For an extra challenge, don't use: // For an extra challenge, don't use:
// - recursion // - recursion
// Execute `rustlings hint iterators4` for hints. // Execute `rustlings hint iterators4` for hints.
if num == 0 {
return 1;
}
(1..num).into_iter().rfold(num, |acc, elem| acc * elem)
} }
#[cfg(test)] #[cfg(test)]

View File

@ -11,8 +11,6 @@
// Execute `rustlings hint iterators5` or use the `hint` watch subcommand for a // Execute `rustlings hint iterators5` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
use std::collections::HashMap; use std::collections::HashMap;
#[derive(Clone, Copy, PartialEq, Eq)] #[derive(Clone, Copy, PartialEq, Eq)]
@ -35,7 +33,13 @@ fn count_for(map: &HashMap<String, Progress>, value: Progress) -> usize {
fn count_iterator(map: &HashMap<String, Progress>, value: Progress) -> usize { fn count_iterator(map: &HashMap<String, Progress>, value: Progress) -> usize {
// map is a hashmap with String keys and Progress values. // map is a hashmap with String keys and Progress values.
// map = { "variables1": Complete, "from_str": None, ... } // map = { "variables1": Complete, "from_str": None, ... }
todo!(); let mut count: usize = 0;
map.iter().for_each(|(k, v)| {
if value == *v {
count += 1;
}
});
count
} }
fn count_collection_for(collection: &[HashMap<String, Progress>], value: Progress) -> usize { fn count_collection_for(collection: &[HashMap<String, Progress>], value: Progress) -> usize {
@ -54,7 +58,11 @@ fn count_collection_iterator(collection: &[HashMap<String, Progress>], value: Pr
// collection is a slice of hashmaps. // collection is a slice of hashmaps.
// collection = [{ "variables1": Complete, "from_str": None, ... }, // collection = [{ "variables1": Complete, "from_str": None, ... },
// { "variables2": Complete, ... }, ... ] // { "variables2": Complete, ... }, ... ]
todo!(); let mut count: usize = 0;
collection.iter().for_each(|m| {
count += count_iterator(m, value);
});
count
} }
#[cfg(test)] #[cfg(test)]

View File

@ -21,19 +21,17 @@
// //
// Execute `rustlings hint arc1` or use the `hint` watch subcommand for a hint. // Execute `rustlings hint arc1` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE
#![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;
use std::thread; use std::thread;
fn main() { fn main() {
let numbers: Vec<_> = (0..100u32).collect(); let numbers: Vec<_> = (0..100u32).collect();
let shared_numbers = // TODO let shared_numbers = Arc::new(numbers);
let mut joinhandles = Vec::new(); let mut joinhandles = Vec::new();
for offset in 0..8 { for offset in 0..8 {
let child_numbers = // TODO let child_numbers: Vec<_> = (1..2).collect();
joinhandles.push(thread::spawn(move || { joinhandles.push(thread::spawn(move || {
let sum: u32 = child_numbers.iter().filter(|&&n| n % 8 == offset).sum(); let sum: u32 = child_numbers.iter().filter(|&&n| n % 8 == offset).sum();
println!("Sum of offset {} is {}", offset, sum); println!("Sum of offset {} is {}", offset, sum);

View File

@ -18,14 +18,14 @@
// //
// Execute `rustlings hint box1` or use the `hint` watch subcommand for a hint. // Execute `rustlings hint box1` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE
#[derive(PartialEq, Debug)] #[derive(PartialEq, Debug)]
pub enum List { pub enum List {
Cons(i32, List), Cons(i32, Box<List>),
Nil, Nil,
} }
use crate::List::{Cons, Nil};
fn main() { fn main() {
println!("This is an empty cons list: {:?}", create_empty_list()); println!("This is an empty cons list: {:?}", create_empty_list());
println!( println!(
@ -35,11 +35,11 @@ fn main() {
} }
pub fn create_empty_list() -> List { pub fn create_empty_list() -> List {
todo!() return Nil;
} }
pub fn create_non_empty_list() -> List { pub fn create_non_empty_list() -> List {
todo!() return Cons(2, Box::new(Cons(5, Box::new(Nil))));
} }
#[cfg(test)] #[cfg(test)]

View File

@ -12,8 +12,6 @@
// //
// Execute `rustlings hint cow1` or use the `hint` watch subcommand for a hint. // Execute `rustlings hint cow1` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE
use std::borrow::Cow; use std::borrow::Cow;
fn abs_all<'a, 'b>(input: &'a mut Cow<'b, [i32]>) -> &'a mut Cow<'b, [i32]> { fn abs_all<'a, 'b>(input: &'a mut Cow<'b, [i32]>) -> &'a mut Cow<'b, [i32]> {
@ -48,7 +46,8 @@ mod tests {
let slice = [0, 1, 2]; let slice = [0, 1, 2];
let mut input = Cow::from(&slice[..]); let mut input = Cow::from(&slice[..]);
match abs_all(&mut input) { match abs_all(&mut input) {
// TODO Cow::Borrowed(_) => Ok(()),
_ => Err("Expected borrowed value"),
} }
} }
@ -60,7 +59,8 @@ mod tests {
let slice = vec![0, 1, 2]; let slice = vec![0, 1, 2];
let mut input = Cow::from(slice); let mut input = Cow::from(slice);
match abs_all(&mut input) { match abs_all(&mut input) {
// TODO Cow::Owned(_) => Ok(()),
_ => Err("Expected owned value"),
} }
} }
@ -72,7 +72,8 @@ mod tests {
let slice = vec![-1, 0, 1]; let slice = vec![-1, 0, 1];
let mut input = Cow::from(slice); let mut input = Cow::from(slice);
match abs_all(&mut input) { match abs_all(&mut input) {
// TODO Cow::Owned(_) => Ok(()),
_ => Err("Expected owned value"),
} }
} }
} }

View File

@ -10,8 +10,6 @@
// //
// Execute `rustlings hint rc1` or use the `hint` watch subcommand for a hint. // Execute `rustlings hint rc1` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE
use std::rc::Rc; use std::rc::Rc;
#[derive(Debug)] #[derive(Debug)]
@ -60,18 +58,15 @@ fn main() {
println!("reference count = {}", Rc::strong_count(&sun)); // 6 references println!("reference count = {}", Rc::strong_count(&sun)); // 6 references
jupiter.details(); jupiter.details();
// TODO let saturn = Planet::Saturn(Rc::clone(&sun));
let saturn = Planet::Saturn(Rc::new(Sun {}));
println!("reference count = {}", Rc::strong_count(&sun)); // 7 references println!("reference count = {}", Rc::strong_count(&sun)); // 7 references
saturn.details(); saturn.details();
// TODO let uranus = Planet::Uranus(Rc::clone(&sun));
let uranus = Planet::Uranus(Rc::new(Sun {}));
println!("reference count = {}", Rc::strong_count(&sun)); // 8 references println!("reference count = {}", Rc::strong_count(&sun)); // 8 references
uranus.details(); uranus.details();
// TODO let neptune = Planet::Neptune(Rc::clone(&sun));
let neptune = Planet::Neptune(Rc::new(Sun {}));
println!("reference count = {}", Rc::strong_count(&sun)); // 9 references println!("reference count = {}", Rc::strong_count(&sun)); // 9 references
neptune.details(); neptune.details();
@ -92,13 +87,13 @@ fn main() {
drop(mars); drop(mars);
println!("reference count = {}", Rc::strong_count(&sun)); // 4 references println!("reference count = {}", Rc::strong_count(&sun)); // 4 references
// TODO drop(earth);
println!("reference count = {}", Rc::strong_count(&sun)); // 3 references println!("reference count = {}", Rc::strong_count(&sun)); // 3 references
// TODO drop(venus);
println!("reference count = {}", Rc::strong_count(&sun)); // 2 references println!("reference count = {}", Rc::strong_count(&sun)); // 2 references
// TODO drop(mercury);
println!("reference count = {}", Rc::strong_count(&sun)); // 1 reference println!("reference count = {}", Rc::strong_count(&sun)); // 1 reference
assert_eq!(Rc::strong_count(&sun), 1); assert_eq!(Rc::strong_count(&sun), 1);

View File

@ -8,8 +8,6 @@
// Execute `rustlings hint threads1` or use the `hint` watch subcommand for a // Execute `rustlings hint threads1` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
use std::thread; use std::thread;
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
@ -27,6 +25,7 @@ fn main() {
let mut results: Vec<u128> = vec![]; let mut results: Vec<u128> = vec![];
for handle in handles { for handle in handles {
// TODO: a struct is returned from thread::spawn, can you use it? // TODO: a struct is returned from thread::spawn, can you use it?
results.push(handle.join().unwrap());
} }
if results.len() != 10 { if results.len() != 10 {

View File

@ -7,9 +7,7 @@
// Execute `rustlings hint threads2` or use the `hint` watch subcommand for a // Execute `rustlings hint threads2` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE use std::sync::{Arc, Mutex};
use std::sync::Arc;
use std::thread; use std::thread;
use std::time::Duration; use std::time::Duration;
@ -18,14 +16,16 @@ struct JobStatus {
} }
fn main() { fn main() {
let status = Arc::new(JobStatus { jobs_completed: 0 }); let status = Arc::new(Mutex::new(JobStatus { jobs_completed: 0 }));
let mut handles = vec![]; let mut handles = vec![];
for _ in 0..10 { for _ in 0..10 {
let status_shared = Arc::clone(&status); let status_shared = Arc::clone(&status);
let handle = thread::spawn(move || { let handle = thread::spawn(move || {
thread::sleep(Duration::from_millis(250)); thread::sleep(Duration::from_millis(250));
// TODO: You must take an action before you update a shared value // TODO: You must take an action before you update a shared value
status_shared.jobs_completed += 1;
let mut job_status = status_shared.lock().unwrap();
job_status.jobs_completed += 1;
}); });
handles.push(handle); handles.push(handle);
} }
@ -34,6 +34,6 @@ fn main() {
// TODO: Print the value of the JobStatus.jobs_completed. Did you notice // TODO: Print the value of the JobStatus.jobs_completed. Did you notice
// anything interesting in the output? Do you have to 'join' on all the // anything interesting in the output? Do you have to 'join' on all the
// handles? // handles?
println!("jobs completed {}", ???); println!("jobs completed {}", status.lock().unwrap().jobs_completed);
} }
} }

View File

@ -3,8 +3,6 @@
// Execute `rustlings hint threads3` or use the `hint` watch subcommand for a // Execute `rustlings hint threads3` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
use std::sync::mpsc; use std::sync::mpsc;
use std::sync::Arc; use std::sync::Arc;
use std::thread; use std::thread;
@ -31,10 +29,11 @@ fn send_tx(q: Queue, tx: mpsc::Sender<u32>) -> () {
let qc1 = Arc::clone(&qc); let qc1 = Arc::clone(&qc);
let qc2 = Arc::clone(&qc); let qc2 = Arc::clone(&qc);
let tx_clone = tx.clone();
thread::spawn(move || { thread::spawn(move || {
for val in &qc1.first_half { for val in &qc1.first_half {
println!("sending {:?}", val); println!("sending {:?}", val);
tx.send(*val).unwrap(); tx_clone.send(*val).unwrap();
thread::sleep(Duration::from_secs(1)); thread::sleep(Duration::from_secs(1));
} }
}); });

View File

@ -3,8 +3,6 @@
// Execute `rustlings hint macros1` or use the `hint` watch subcommand for a // Execute `rustlings hint macros1` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
macro_rules! my_macro { macro_rules! my_macro {
() => { () => {
println!("Check out my macro!"); println!("Check out my macro!");
@ -12,5 +10,5 @@ macro_rules! my_macro {
} }
fn main() { fn main() {
my_macro(); my_macro!();
} }

View File

@ -3,14 +3,12 @@
// Execute `rustlings hint macros2` or use the `hint` watch subcommand for a // Execute `rustlings hint macros2` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
fn main() {
my_macro!();
}
macro_rules! my_macro { macro_rules! my_macro {
() => { () => {
println!("Check out my macro!"); println!("Check out my macro!");
}; };
} }
fn main() {
my_macro!();
}

View File

@ -5,8 +5,7 @@
// Execute `rustlings hint macros3` or use the `hint` watch subcommand for a // Execute `rustlings hint macros3` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE #[macro_use]
mod macros { mod macros {
macro_rules! my_macro { macro_rules! my_macro {
() => { () => {

View File

@ -3,13 +3,11 @@
// Execute `rustlings hint macros4` or use the `hint` watch subcommand for a // Execute `rustlings hint macros4` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
#[rustfmt::skip] #[rustfmt::skip]
macro_rules! my_macro { macro_rules! my_macro {
() => { () => {
println!("Check out my macro!"); println!("Check out my macro!");
} };
($val:expr) => { ($val:expr) => {
println!("Look at this other macro: {}", $val); println!("Look at this other macro: {}", $val);
} }

7
exercises/22_clippy/Cargo.lock generated Normal file
View File

@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "clippy3"
version = "0.0.1"

View File

@ -0,0 +1,7 @@
[package]
name = "clippy3"
version = "0.0.1"
edition = "2021"
[[bin]]
name = "clippy3"
path = "clippy3.rs"

View File

@ -9,12 +9,10 @@
// Execute `rustlings hint clippy1` or use the `hint` watch subcommand for a // Execute `rustlings hint clippy1` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
use std::f32; use std::f32;
fn main() { fn main() {
let pi = 3.14f32; let pi = f32::consts::PI;
let radius = 5.00f32; let radius = 5.00f32;
let area = pi * f32::powi(radius, 2); let area = pi * f32::powi(radius, 2);

View File

@ -1,14 +1,12 @@
// clippy2.rs // clippy2.rs
// //
// Execute `rustlings hint clippy2` or use the `hint` watch subcommand for a // Execute `rustlings hint clippy2` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
fn main() { fn main() {
let mut res = 42; let mut res = 42;
let option = Some(12); let option = Some(12);
for x in option { if let Some(x) = option {
res += x; res += x;
} }
println!("{}", res); println!("{}", res);

View File

@ -1,30 +1,25 @@
// clippy3.rs // 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. // No hints.
// I AM NOT DONE
#[allow(unused_variables, unused_assignments)] #[allow(unused_variables, unused_assignments)]
fn main() { fn main() {
let my_option: Option<()> = None; let my_option: Option<()> = None;
if my_option.is_none() { if my_option.is_none() {
my_option.unwrap(); println!("This is none!");
} }
let my_arr = &[ let my_arr = &[-1, -2, -3, -4, -5, -6];
-1, -2, -3
-4, -5, -6
];
println!("My array! Here it is: {:?}", my_arr); 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); println!("This Vec is empty, see? {:?}", my_empty_vec);
let mut value_a = 45; let mut value_a = 45;
let mut value_b = 66; let mut value_b = 66;
// Let's swap these two! // Let's swap these two!
value_a = value_b; std::mem::swap(&mut value_a, &mut value_b);
value_b = value_a;
println!("value a: {}; value b: {}", value_a, value_b); println!("value a: {}; value b: {}", value_a, value_b);
} }

View File

@ -7,25 +7,23 @@
// Execute `rustlings hint as_ref_mut` or use the `hint` watch subcommand for a // Execute `rustlings hint as_ref_mut` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
// 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.
fn byte_counter<T>(arg: T) -> usize { fn byte_counter<T: AsRef<str>>(arg: T) -> usize {
arg.as_ref().as_bytes().len() arg.as_ref().as_bytes().len()
} }
// Obtain the number of characters (not bytes) in the given argument. // Obtain the number of characters (not bytes) in the given argument.
// TODO: Add the AsRef trait appropriately as a trait bound. // 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() arg.as_ref().chars().count()
} }
// Squares a number using as_mut(). // Squares a number using as_mut().
// TODO: Add the appropriate trait bound. // TODO: Add the appropriate trait bound.
fn num_sq<T>(arg: &mut T) { fn num_sq<T: AsMut<u32>>(arg: &mut T) {
// TODO: Implement the function body. // TODO: Implement the function body.
??? *arg.as_mut() = *arg.as_mut() * *arg.as_mut()
} }
#[cfg(test)] #[cfg(test)]

View File

@ -40,10 +40,40 @@ impl Default for Person {
// If while parsing the age, something goes wrong, then return the default of // If while parsing the age, something goes wrong, then return the default of
// Person Otherwise, then return an instantiated Person object with the results // Person Otherwise, then return an instantiated Person object with the results
// I AM NOT DONE
impl From<&str> for Person { impl From<&str> for Person {
fn from(s: &str) -> Person { fn from(s: &str) -> Person {
let mut person = Person {
name: "".to_string(),
age: 0,
};
let mut split_it = s.split(',');
if let Some(name) = split_it.next() {
println!("{}", name);
if !name.is_empty() {
person.name = String::from(name);
} else {
return Person::default();
}
} else {
return Person::default();
}
if let Some(age_str) = split_it.next() {
if age_str.is_empty() {
return Person::default();
}
if let Ok(age) = age_str.parse::<usize>() {
person.age = age;
} else {
return Person::default();
}
} else {
return Person::default();
}
person
} }
} }

View File

@ -31,8 +31,6 @@ enum ParsePersonError {
ParseInt(ParseIntError), ParseInt(ParseIntError),
} }
// I AM NOT DONE
// Steps: // Steps:
// 1. If the length of the provided string is 0, an error should be returned // 1. If the length of the provided string is 0, an error should be returned
// 2. Split the given string on the commas present in it // 2. Split the given string on the commas present in it
@ -52,6 +50,42 @@ enum ParsePersonError {
impl FromStr for Person { impl FromStr for Person {
type Err = ParsePersonError; type Err = ParsePersonError;
fn from_str(s: &str) -> Result<Person, Self::Err> { fn from_str(s: &str) -> Result<Person, Self::Err> {
if s.is_empty() {
return Err(ParsePersonError::Empty);
}
let mut person = Person {
age: 0,
name: "".to_string(),
};
let mut split_it = s.split(',');
let first = split_it.next();
if let Some(name) = first {
if !name.is_empty() {
person.name = String::from(name);
} else {
return Err(ParsePersonError::NoName);
}
}
if let Some(age_str) = split_it.next() {
match age_str.parse::<usize>() {
Ok(age) => person.age = age,
Err(err) => {
return Err(ParsePersonError::ParseInt(err));
}
}
} else {
return Err(ParsePersonError::BadLen);
}
if let Some(extra) = split_it.next() {
return Err(ParsePersonError::BadLen);
}
Ok(person)
} }
} }

View File

@ -27,8 +27,6 @@ enum IntoColorError {
IntConversion, IntConversion,
} }
// I AM NOT DONE
// Your task is to complete this implementation and return an Ok result of inner // Your task is to complete this implementation and return an Ok result of inner
// type Color. You need to create an implementation for a tuple of three // type Color. You need to create an implementation for a tuple of three
// integers, an array of three integers, and a slice of integers. // integers, an array of three integers, and a slice of integers.
@ -41,6 +39,18 @@ enum IntoColorError {
impl TryFrom<(i16, i16, i16)> for Color { impl TryFrom<(i16, i16, i16)> for Color {
type Error = IntoColorError; 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> {
if (tuple.0.is_negative() || tuple.0 > 255)
|| (tuple.1.is_negative() || tuple.1 > 255)
|| (tuple.2.is_negative() || tuple.2 > 255)
{
return Err(IntoColorError::IntConversion);
}
return Ok(Color {
red: tuple.0 as u8,
green: tuple.1 as u8,
blue: tuple.2 as u8,
});
} }
} }
@ -48,6 +58,18 @@ impl TryFrom<(i16, i16, i16)> for Color {
impl TryFrom<[i16; 3]> for Color { impl TryFrom<[i16; 3]> for Color {
type Error = IntoColorError; type Error = IntoColorError;
fn try_from(arr: [i16; 3]) -> Result<Self, Self::Error> { fn try_from(arr: [i16; 3]) -> Result<Self, Self::Error> {
if (arr[0].is_negative() || arr[0] > 255)
|| (arr[1].is_negative() || arr[1] > 255)
|| (arr[2].is_negative() || arr[2] > 255)
{
return Err(IntoColorError::IntConversion);
}
return Ok(Color {
red: arr[0] as u8,
green: arr[1] as u8,
blue: arr[2] as u8,
});
} }
} }
@ -55,6 +77,21 @@ impl TryFrom<[i16; 3]> for Color {
impl TryFrom<&[i16]> for Color { impl TryFrom<&[i16]> for Color {
type Error = IntoColorError; 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 {
return Err(IntoColorError::BadLen);
}
if (slice[0].is_negative() || slice[0] > 255)
|| (slice[1].is_negative() || slice[1] > 255)
|| (slice[2].is_negative() || slice[2] > 255)
{
return Err(IntoColorError::IntConversion);
}
return Ok(Color {
red: slice[0] as u8,
green: slice[1] as u8,
blue: slice[2] as u8,
});
} }
} }

View File

@ -10,11 +10,9 @@
// Execute `rustlings hint using_as` or use the `hint` watch subcommand for a // Execute `rustlings hint using_as` or use the `hint` watch subcommand for a
// hint. // hint.
// I AM NOT DONE
fn average(values: &[f64]) -> f64 { fn average(values: &[f64]) -> f64 {
let total = values.iter().sum::<f64>(); let total = values.iter().sum::<f64>();
total / values.len() total / values.len() as f64
} }
fn main() { fn main() {

View File

@ -13,10 +13,15 @@
// //
// No hints this time ;) // No hints this time ;)
// I AM NOT DONE
// Put your function here! // Put your function here!
// fn calculate_price_of_apples { fn calculate_price_of_apples(apples: u64) -> u64 {
if apples > 40 {
apples
} else {
apples * 2
}
}
// Don't modify this function! // Don't modify this function!
#[test] #[test]

View File

@ -20,8 +20,6 @@
// //
// No hints this time! // No hints this time!
// I AM NOT DONE
pub enum Command { pub enum Command {
Uppercase, Uppercase,
Trim, Trim,
@ -32,11 +30,22 @@ mod my_module {
use super::Command; use super::Command;
// TODO: Complete the function signature! // TODO: Complete the function signature!
pub fn transformer(input: ???) -> ??? { pub fn transformer(input: Vec<(String, Command)>) -> Vec<String> {
// TODO: Complete the output declaration! // TODO: Complete the output declaration!
let mut output: ??? = vec![]; let mut output: Vec<String> = vec![];
for (string, command) in input.iter() { for (string, command) in input.iter() {
// TODO: Complete the function body. You can do it! // TODO: Complete the function body. You can do it!
match command {
Command::Trim => output.push(string.trim().to_string()),
Command::Uppercase => output.push(string.to_uppercase()),
Command::Append(size) => {
let mut buf: String = string.to_owned();
for n in 0..*size {
buf += "bar";
}
output.push(buf)
}
}
} }
output output
} }
@ -45,12 +54,12 @@ mod my_module {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
// TODO: What do we need to import to have `transformer` in scope? // TODO: What do we need to import to have `transformer` in scope?
use ???;
use super::Command; use super::Command;
use crate::my_module;
#[test] #[test]
fn it_works() { fn it_works() {
let output = transformer(vec![ let output = my_module::transformer(vec![
("hello".into(), Command::Uppercase), ("hello".into(), Command::Uppercase),
(" all roads lead to rome! ".into(), Command::Trim), (" all roads lead to rome! ".into(), Command::Trim),
("foo".into(), Command::Append(1)), ("foo".into(), Command::Append(1)),

View File

@ -16,18 +16,18 @@
// //
// Execute `rustlings hint quiz3` or use the `hint` watch subcommand for a hint. // Execute `rustlings hint quiz3` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE pub struct ReportCard<T> {
pub grade: T,
pub struct ReportCard {
pub grade: f32,
pub student_name: String, pub student_name: String,
pub student_age: u8, pub student_age: u8,
} }
impl ReportCard { impl<T: std::fmt::Display> ReportCard<T> {
pub fn print(&self) -> String { pub fn print(&self) -> String {
format!("{} ({}) - achieved a grade of {}", format!(
&self.student_name, &self.student_age, &self.grade) "{} ({}) - achieved a grade of {}",
&self.student_name, &self.student_age, &self.grade
)
} }
} }
@ -52,7 +52,7 @@ mod tests {
fn generate_alphabetic_report_card() { fn generate_alphabetic_report_card() {
// TODO: Make sure to change the grade here after you finish the exercise. // TODO: Make sure to change the grade here after you finish the exercise.
let report_card = ReportCard { let report_card = ReportCard {
grade: 2.1, grade: String::from("A+"),
student_name: "Gary Plotter".to_string(), student_name: "Gary Plotter".to_string(),
student_age: 11, student_age: 11,
}; };