Compare commits

...

6 commits

Author SHA1 Message Date
Enrico 4745ec54e2
Merge e59c65cf45 into e6cb104294 2024-11-12 12:42:41 +01:00
mo8it e6cb104294 chore: Release 2024-11-11 15:51:27 +01:00
mo8it 410eb69d25 Remove "chore: " from the commit message of releases 2024-11-11 15:49:50 +01:00
mo8it 243cf5f261 Update CHANGELOG 2024-11-11 15:49:24 +01:00
Enrico e59c65cf45 chore: Refactored to adhere to new rustlings version 2024-09-29 20:58:33 +02:00
Enrico 1c27aeead9 feat: add functions6.rs and move_semantics6.rs exercises about closures 2024-09-28 11:59:09 +02:00
11 changed files with 138 additions and 8 deletions

View file

@ -1,3 +1,34 @@
<a name="6.4.0"></a>
## 6.4.0 (2024-11-11)
### Added
- The list of exercises is now searchable by pressing `s` or `/` 🔍️ (thanks to [@frroossst](https://github.com/frroossst))
- New option `c` in the prompt to manually check all exercises ✅ (thanks to [@Nahor](https://github.com/Nahor))
- New command `check-all` to manually check all exercises ✅ (thanks to [@Nahor](https://github.com/Nahor))
- Addictive animation for showing the progress of checking all exercises. A nice showcase of parallelism in Rust ✨
- New option `x` in the prompt to reset the file of the current exercise 🔄
- Allow `dead_code` for all exercises and solutions ⚰️ (thanks to [@huss4in](https://github.com/huss4in))
- Pause input while running an exercise to avoid unexpected prompt interactions ⏸️
- Limit the maximum number of exercises to 999. Any third-party exercises willing to reach that limit? 🔝
### Changed
- `enums3`: Remove redundant enum definition task (thanks to [@senekor](https://github.com/senekor))
- `if2`: Make the exercise less confusing by avoiding "fizz", "fuzz", "foo", "bar" and "baz" (thanks to [@senekor](https://github.com/senekor))
- `hashmap3`: Use the method `Entry::or_default`.
- Update the state of all exercises when checking all of them (thanks to [@Nahor](https://github.com/Nahor))
- The main prompt doesn't need a confirmation with ENTER on Unix-like systems anymore.
- No more jumping back to a previous exercise when its file is changed. Use the list to jump between exercises.
- Dump the solution file after an exercise is done even if the solution's directory doesn't exist.
- Rework the footer in the list.
- Optimize the file watcher.
### Fixed
- Fix bad contrast in the list on terminals with a light theme.
<a name="6.3.0"></a> <a name="6.3.0"></a>
## 6.3.0 (2024-08-29) ## 6.3.0 (2024-08-29)
@ -113,7 +144,7 @@ You can read about the motivations of this change in [this issue](https://github
### List mode ### List mode
A list mode was added using [Ratatui](https://ratatui.rs). A new list mode was added!
You can enter it by entering `l` in the watch mode. You can enter it by entering `l` in the watch mode.
It offers the following features: It offers the following features:
@ -814,7 +845,7 @@ Then follow the link to the guide about [third-party exercises](THIRD_PARTY_EXER
#### Bug Fixes #### Bug Fixes
- Update deps to version compatable with aarch64-pc-windows (#263) ([19a93428](https://github.com/rust-lang/rustlings/commit/19a93428b3c73d994292671f829bdc8e5b7b3401)) - Update deps to version compatible with aarch64-pc-windows (#263) ([19a93428](https://github.com/rust-lang/rustlings/commit/19a93428b3c73d994292671f829bdc8e5b7b3401))
- **docs:** - **docs:**
- Added a necessary step to Windows installation process (#242) ([3906efcd](https://github.com/rust-lang/rustlings/commit/3906efcd52a004047b460ed548037093de3f523f)) - Added a necessary step to Windows installation process (#242) ([3906efcd](https://github.com/rust-lang/rustlings/commit/3906efcd52a004047b460ed548037093de3f523f))
- Fixed mangled sentence from book; edited for clarity (#266) ([ade52ff](https://github.com/rust-lang/rustlings/commit/ade52ffb739987287ddd5705944c8777705faed9)) - Fixed mangled sentence from book; edited for clarity (#266) ([ade52ff](https://github.com/rust-lang/rustlings/commit/ade52ffb739987287ddd5705944c8777705faed9))

4
Cargo.lock generated
View file

@ -451,7 +451,7 @@ dependencies = [
[[package]] [[package]]
name = "rustlings" name = "rustlings"
version = "6.3.0" version = "6.4.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"clap", "clap",
@ -468,7 +468,7 @@ dependencies = [
[[package]] [[package]]
name = "rustlings-macros" name = "rustlings-macros"
version = "6.3.0" version = "6.4.0"
dependencies = [ dependencies = [
"quote", "quote",
"serde", "serde",

View file

@ -6,7 +6,7 @@ exclude = [
] ]
[workspace.package] [workspace.package]
version = "6.3.0" version = "6.4.0"
authors = [ authors = [
"Mo Bitar <mo8it@proton.me>", # https://github.com/mo8it "Mo Bitar <mo8it@proton.me>", # https://github.com/mo8it
"Liv <mokou@fastmail.com>", # https://github.com/shadows-withal "Liv <mokou@fastmail.com>", # https://github.com/shadows-withal
@ -51,7 +51,7 @@ clap = { version = "4.5.20", features = ["derive"] }
crossterm = { version = "0.28.1", default-features = false, features = ["windows", "events"] } crossterm = { version = "0.28.1", default-features = false, features = ["windows", "events"] }
notify = "7.0.0" notify = "7.0.0"
os_pipe = "1.2.1" os_pipe = "1.2.1"
rustlings-macros = { path = "rustlings-macros", version = "=6.3.0" } rustlings-macros = { path = "rustlings-macros", version = "=6.4.0" }
serde_json = "1.0.132" serde_json = "1.0.132"
serde.workspace = true serde.workspace = true
toml_edit.workspace = true toml_edit.workspace = true
@ -70,6 +70,7 @@ panic = "abort"
[package.metadata.release] [package.metadata.release]
pre-release-hook = ["./release-hook.sh"] pre-release-hook = ["./release-hook.sh"]
pre-release-commit-message = "Release 🎉"
[workspace.lints.rust] [workspace.lints.rust]
unsafe_code = "forbid" unsafe_code = "forbid"

View file

@ -26,6 +26,8 @@ bin = [
{ name = "functions4_sol", path = "../solutions/02_functions/functions4.rs" }, { name = "functions4_sol", path = "../solutions/02_functions/functions4.rs" },
{ name = "functions5", path = "../exercises/02_functions/functions5.rs" }, { name = "functions5", path = "../exercises/02_functions/functions5.rs" },
{ name = "functions5_sol", path = "../solutions/02_functions/functions5.rs" }, { name = "functions5_sol", path = "../solutions/02_functions/functions5.rs" },
{ name = "functions6", path = "../exercises/02_functions/functions6.rs" },
{ name = "functions6_sol", path = "../solutions/02_functions/functions6.rs" },
{ name = "if1", path = "../exercises/03_if/if1.rs" }, { name = "if1", path = "../exercises/03_if/if1.rs" },
{ name = "if1_sol", path = "../solutions/03_if/if1.rs" }, { name = "if1_sol", path = "../solutions/03_if/if1.rs" },
{ name = "if2", path = "../exercises/03_if/if2.rs" }, { name = "if2", path = "../exercises/03_if/if2.rs" },
@ -60,6 +62,8 @@ bin = [
{ name = "move_semantics4_sol", path = "../solutions/06_move_semantics/move_semantics4.rs" }, { name = "move_semantics4_sol", path = "../solutions/06_move_semantics/move_semantics4.rs" },
{ name = "move_semantics5", path = "../exercises/06_move_semantics/move_semantics5.rs" }, { name = "move_semantics5", path = "../exercises/06_move_semantics/move_semantics5.rs" },
{ name = "move_semantics5_sol", path = "../solutions/06_move_semantics/move_semantics5.rs" }, { name = "move_semantics5_sol", path = "../solutions/06_move_semantics/move_semantics5.rs" },
{ name = "move_semantics6", path = "../exercises/06_move_semantics/move_semantics6.rs" },
{ name = "move_semantics6_sol", path = "../solutions/06_move_semantics/move_semantics6.rs" },
{ name = "structs1", path = "../exercises/07_structs/structs1.rs" }, { name = "structs1", path = "../exercises/07_structs/structs1.rs" },
{ name = "structs1_sol", path = "../solutions/07_structs/structs1.rs" }, { name = "structs1_sol", path = "../solutions/07_structs/structs1.rs" },
{ name = "structs2", path = "../exercises/07_structs/structs2.rs" }, { name = "structs2", path = "../exercises/07_structs/structs2.rs" },

View file

@ -1,8 +1,9 @@
# Functions # Functions
Here, you'll learn how to write functions and how the Rust compiler can help you debug errors even Here, you'll learn how to write functions and how the Rust compiler can help you debug errors even
in more complex code. in more complex code. You will also learn what is the difference with closures.
## Further information ## Further information
- [How Functions Work](https://doc.rust-lang.org/book/ch03-03-how-functions-work.html) - [How Functions Work](https://doc.rust-lang.org/book/ch03-03-how-functions-work.html)
- [Closures](https://doc.rust-lang.org/book/ch13-01-closures.html)

View file

@ -0,0 +1,19 @@
// functions6.rs
//
// Here you can practice special functions called `closures`, that can capture
// variables of their parent context.
// Fix the code below to make it compile, without changing the two closure
// definitions.
//
// Execute `rustlings hint functions6` or use the `hint` watch subcommand for
// some hints.
fn main() {
// TODO: ensure the definition of captured variable
let closure_1 = |input_var: u32| -> u32 {input_var + outer_var};
println!("Closure#1 returns {}", closure_1(5));
let closure_2 = |input_var| println!("Closure#2 (input_var {})", input_var);
closure_2(2);
closure_2("5"); // TODO: look at the captured variable type here
}

View file

@ -0,0 +1,25 @@
// move_semantics6.rs
//
// Here you will practice how mutable/immutable borrowing works in the context
// of a closure.
//
// Try to fix this code to make it compile and not panic.
// You can't change anything except removing 1 line.
//
// Execute `rustlings hint move_semantics7` or use the `hint` watch subcommand
// for a hint.
fn main() {
let mut counter = 0;
let mut increment = || {
counter += 1;
println!("counter equals {}", counter);
};
increment();
let _reborrowed_counter = &counter; // TODO: figure out where to put this borrowing instruction
increment();
assert_eq!(counter, 2);
}

View file

@ -3,7 +3,7 @@
| Exercise | Book Chapter | | Exercise | Book Chapter |
| ---------------------- | ------------------- | | ---------------------- | ------------------- |
| variables | §3.1 | | variables | §3.1 |
| functions | §3.3 | | functions | §3.3, §13.1 |
| if | §3.5 | | if | §3.5 |
| primitive_types | §3.2, §4.3 | | primitive_types | §3.2, §4.3 |
| vecs | §8.1 | | vecs | §8.1 |

View file

@ -187,6 +187,20 @@ There are two solutions:
1. Add the `return` keyword before `num * num;` 1. Add the `return` keyword before `num * num;`
2. Remove the semicolon `;` after `num * num`""" 2. Remove the semicolon `;` after `num * num`"""
[[exercises]]
name = "functions6"
dir = "02_functions"
test = false
hint = """
Hint FIX #1: Closures can capture variables defined in the outer context.
Hint FIX #2: Closures can infer both input and returned types, when they are not
specified in the signature. But the closure cannot be reused with different
input types.
Read more about closures in the rust book dedicated section:
https://doc.rust-lang.org/book/ch13-01-closures.html"""
# IF # IF
[[exercises]] [[exercises]]
@ -391,6 +405,18 @@ The first problem is that `get_char` is taking ownership of the string. So
Once you've fixed that, `string_uppercase`'s function signature will also need Once you've fixed that, `string_uppercase`'s function signature will also need
to be adjusted.""" to be adjusted."""
[[exercises]]
name = "move_semantics6"
dir = "06_move_semantics"
test = false
hint = """
When a closure captures a variable to modify it, it actually borrows that variable
as a mutable reference. In this exercise, the closure mutably borrows the `counter`
variable, thus, any attempt to borrow `counter` between closure calls leads to an error.
You cannot immutably borrow a variable if a mutable closure is
called later in the scope."""
# STRUCTS # STRUCTS
[[exercises]] [[exercises]]

View file

@ -0,0 +1,9 @@
fn main() {
let outer_var = 1;
let closure_1 = |input_var: u32| -> u32 { input_var + outer_var };
println!("Closure#1 returns {}", closure_1(5));
let closure_2 = |input_var| println!("Closure#2 (input_var {})", input_var);
closure_2(2);
closure_2(5);
}

View file

@ -0,0 +1,14 @@
fn main() {
let mut counter = 0;
let mut increment = || {
counter += 1;
println!("counter equals {}", counter);
};
increment();
increment();
let _reborrowed_counter = &counter;
assert_eq!(counter, 2);
}