From fef8314d3d45aa1ec3655cd6e9a52f877da51c23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20T=C3=B6rnquist?= Date: Sat, 18 Feb 2023 18:43:34 +0100 Subject: [PATCH 01/58] fix(move_semantics2): add expected output comment You can easily get this to compile with `vec0` being `[]` and `vec1` being `[22, 44, 66, 88]` --- exercises/move_semantics/move_semantics2.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/exercises/move_semantics/move_semantics2.rs b/exercises/move_semantics/move_semantics2.rs index 64870850..68dbf021 100644 --- a/exercises/move_semantics/move_semantics2.rs +++ b/exercises/move_semantics/move_semantics2.rs @@ -2,6 +2,10 @@ // Make me compile without changing line 13 or moving line 10! // Execute `rustlings hint move_semantics2` or use the `hint` watch subcommand for a hint. +// Expected output: +// vec0 has length 3 content `[22, 44, 66]` +// vec1 has length 4 content `[22, 44, 66, 88]` + // I AM NOT DONE fn main() { From 89069f78b165e2e10d0b0a72c8d6b246bb9e9c94 Mon Sep 17 00:00:00 2001 From: Alex Date: Sat, 18 Feb 2023 19:26:40 +0000 Subject: [PATCH 02/58] chore: update move_semantics4.rs' hint after #144, the signature doesn't need changing anymore --- info.toml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/info.toml b/info.toml index 2f424033..431b49ff 100644 --- a/info.toml +++ b/info.toml @@ -325,8 +325,7 @@ doing one step and then fixing the compiler errors that result! So the end goal is to: - get rid of the first line in main that creates the new vector - so then `vec0` doesn't exist, so we can't pass it to `fill_vec` - - we don't want to pass anything to `fill_vec`, so its signature should - reflect that it does not take any arguments + - `fill_vec` has had its signature changed, which our call should reflect - since we're not creating a new vec in `main` anymore, we need to create a new vec in `fill_vec`, similarly to the way we did in `main`""" From 1ac66f372b670f5218334c1bb0dadcb67ca5cbd4 Mon Sep 17 00:00:00 2001 From: Aaron Suggs Date: Tue, 21 Feb 2023 09:45:59 -0500 Subject: [PATCH 03/58] docs: clarify instructions on iterators5.rs I changed the sentence that referenced the imperative implementation in iterators5.rs. That implementation was already removed and replaced with `todo!()` --- exercises/iterators/iterators5.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/exercises/iterators/iterators5.rs b/exercises/iterators/iterators5.rs index 0593d123..87097956 100644 --- a/exercises/iterators/iterators5.rs +++ b/exercises/iterators/iterators5.rs @@ -2,13 +2,11 @@ // Let's define a simple model to track Rustlings exercise progress. Progress // will be modelled using a hash map. The name of the exercise is the key and // the progress is the value. Two counting functions were created to count the -// number of exercises with a given progress. These counting functions use -// imperative style for loops. Recreate this counting functionality using -// iterators. Only the two iterator methods (count_iterator and -// count_collection_iterator) need to be modified. +// number of exercises with a given progress. Recreate this counting +// functionality using iterators. Try not to use imperative loops (for, while). +// Only the two iterator methods (count_iterator and count_collection_iterator) +// need to be modified. // Execute `rustlings hint iterators5` or use the `hint` watch subcommand for a hint. -// -// Make the code compile and the tests pass. // I AM NOT DONE From 382e16eb7ea66cddc4860f4b19453b031a2a8a8a Mon Sep 17 00:00:00 2001 From: Ali Afsharzadeh Date: Thu, 30 Mar 2023 19:53:22 +0330 Subject: [PATCH 04/58] feat(docs): add markdown linter for exercises README.md files --- .github/workflows/lint.yml | 18 ++++++++++++++++++ .markdownlint.yml | 2 ++ exercises/conversions/README.md | 4 +++- exercises/hashmaps/README.md | 3 ++- exercises/lifetimes/README.md | 12 ++++++------ exercises/macros/README.md | 2 +- exercises/options/README.md | 3 ++- exercises/smart_pointers/README.md | 1 + exercises/traits/README.md | 2 +- 9 files changed, 36 insertions(+), 11 deletions(-) create mode 100644 .github/workflows/lint.yml create mode 100644 .markdownlint.yml diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 00000000..67339d1b --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,18 @@ +name: Lint + +on: + push: + branches: + - main + pull_request: + branches: + - main + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: DavidAnson/markdownlint-cli2-action@v9 + with: + globs: "exercises/**/*.md" diff --git a/.markdownlint.yml b/.markdownlint.yml new file mode 100644 index 00000000..d5f7e391 --- /dev/null +++ b/.markdownlint.yml @@ -0,0 +1,2 @@ +# MD013/line-length Line length, Expected: 80 +MD013: false diff --git a/exercises/conversions/README.md b/exercises/conversions/README.md index 8d7da93e..619a78c5 100644 --- a/exercises/conversions/README.md +++ b/exercises/conversions/README.md @@ -6,6 +6,7 @@ The simplest form of type conversion is a type cast expression. It is denoted wi Rust also offers traits that facilitate type conversions upon implementation. These traits can be found under the [`convert`](https://doc.rust-lang.org/std/convert/index.html) module. The traits are the following: + - `From` and `Into` covered in [`from_into`](from_into.rs) - `TryFrom` and `TryInto` covered in [`try_from_into`](try_from_into.rs) - `AsRef` and `AsMut` covered in [`as_ref_mut`](as_ref_mut.rs) @@ -17,5 +18,6 @@ These should be the main ways ***within the standard library*** to convert data ## Further information These are not directly covered in the book, but the standard library has a great documentation for it. + - [conversions](https://doc.rust-lang.org/std/convert/index.html) -- [`FromStr` trait](https://doc.rust-lang.org/std/str/trait.FromStr.html) \ No newline at end of file +- [`FromStr` trait](https://doc.rust-lang.org/std/str/trait.FromStr.html) diff --git a/exercises/hashmaps/README.md b/exercises/hashmaps/README.md index 30471cf9..80ec1441 100644 --- a/exercises/hashmaps/README.md +++ b/exercises/hashmaps/README.md @@ -1,6 +1,7 @@ # Hashmaps + A *hash map* allows you to associate a value with a particular key. -You may also know this by the names [*unordered map* in C++](https://en.cppreference.com/w/cpp/container/unordered_map), +You may also know this by the names [*unordered map* in C++](https://en.cppreference.com/w/cpp/container/unordered_map), [*dictionary* in Python](https://docs.python.org/3/tutorial/datastructures.html#dictionaries) or an *associative array* in other languages. This is the other data structure that we've been talking about before, when diff --git a/exercises/lifetimes/README.md b/exercises/lifetimes/README.md index 74a4a786..91373f73 100644 --- a/exercises/lifetimes/README.md +++ b/exercises/lifetimes/README.md @@ -3,17 +3,17 @@ Lifetimes tell the compiler how to check whether references live long enough to be valid in any given situation. For example lifetimes say "make sure parameter 'a' lives as long as parameter 'b' so that the return -value is valid". +value is valid". -They are only necessary on borrows, i.e. references, +They are only necessary on borrows, i.e. references, since copied parameters or moves are owned in their scope and cannot be referenced outside. Lifetimes mean that calling code of e.g. functions -can be checked to make sure their arguments are valid. Lifetimes are +can be checked to make sure their arguments are valid. Lifetimes are restrictive of their callers. -If you'd like to learn more about lifetime annotations, the -[lifetimekata](https://tfpk.github.io/lifetimekata/) project -has a similar style of exercises to Rustlings, but is all about +If you'd like to learn more about lifetime annotations, the +[lifetimekata](https://tfpk.github.io/lifetimekata/) project +has a similar style of exercises to Rustlings, but is all about learning to write lifetime annotations. ## Further information diff --git a/exercises/macros/README.md b/exercises/macros/README.md index e34bc3a8..337816d6 100644 --- a/exercises/macros/README.md +++ b/exercises/macros/README.md @@ -4,7 +4,7 @@ Rust's macro system is very powerful, but also kind of difficult to wrap your head around. We're not going to teach you how to write your own fully-featured macros. Instead, we'll show you how to use and create them. -If you'd like to learn more about writing your own macros, the +If you'd like to learn more about writing your own macros, the [macrokata](https://github.com/tfpk/macrokata) project has a similar style of exercises to Rustlings, but is all about learning to write Macros. diff --git a/exercises/options/README.md b/exercises/options/README.md index 6140a167..bdd33749 100644 --- a/exercises/options/README.md +++ b/exercises/options/README.md @@ -1,7 +1,8 @@ # Options -Type Option represents an optional value: every Option is either Some and contains a value, or None, and does not. +Type Option represents an optional value: every Option is either Some and contains a value, or None, and does not. Option types are very common in Rust code, as they have a number of uses: + - Initial values - Return values for functions that are not defined over their entire input range (partial functions) - Return value for otherwise reporting simple errors, where None is returned on error diff --git a/exercises/smart_pointers/README.md b/exercises/smart_pointers/README.md index c517ae31..d56d2b62 100644 --- a/exercises/smart_pointers/README.md +++ b/exercises/smart_pointers/README.md @@ -1,4 +1,5 @@ # Smart Pointers + In Rust, smart pointers are variables that contain an address in memory and reference some other data, but they also have additional metadata and capabilities. Smart pointers in Rust often own the data they point to, while references only borrow data. diff --git a/exercises/traits/README.md b/exercises/traits/README.md index de67acd0..ac87c64e 100644 --- a/exercises/traits/README.md +++ b/exercises/traits/README.md @@ -7,13 +7,13 @@ Data types can implement traits. To do so, the methods making up the trait are d In this way, traits are somewhat similar to Java interfaces and C++ abstract classes. Some additional common Rust traits include: + - `Clone` (the `clone` method) - `Display` (which allows formatted display via `{}`) - `Debug` (which allows formatted display via `{:?}`) Because traits indicate shared behavior between data types, they are useful when writing generics. - ## Further information - [Traits](https://doc.rust-lang.org/book/ch10-02-traits.html) From 27b75795666cddd3725c323cbc0b68b206fc150e Mon Sep 17 00:00:00 2001 From: poneciak Date: Wed, 5 Apr 2023 08:18:51 +0200 Subject: [PATCH 05/58] created task --- exercises/tests/tests4.rs | 40 +++++++++++++++++++++++++++++++++++++++ info.toml | 10 ++++++++++ 2 files changed, 50 insertions(+) create mode 100644 exercises/tests/tests4.rs diff --git a/exercises/tests/tests4.rs b/exercises/tests/tests4.rs new file mode 100644 index 00000000..2d8dd130 --- /dev/null +++ b/exercises/tests/tests4.rs @@ -0,0 +1,40 @@ +// tests4.rs +// Correct the tests to +// Do not change Rectangle::new body +// Execute `rustlings hint tests4` or use the `hint` watch subcommand for a hint. + +// I AM NOT DONE + +struct Rectangle { + width: i32, + height: i32 +} + +impl Rectangle { + pub fn new(width: i32, height: i32) -> Self { + if width < 0 || height < 0 { + panic!("Rectangle width and height cannot be negative!") + } + Rectangle {width, height} + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn correct_width_and_height() { + let _rect = Rectangle::new(10, 10); + } + + #[test] + fn negative_width() { + let _rect = Rectangle::new(-10, 10); + } + + #[test] + fn negative_height() { + let _rect = Rectangle::new(10, -10); + } +} diff --git a/info.toml b/info.toml index ef891435..ad06b888 100644 --- a/info.toml +++ b/info.toml @@ -807,6 +807,16 @@ You can call a function right where you're passing arguments to `assert!` -- so something like `assert!(having_fun())`. If you want to check that you indeed get false, you can negate the result of what you're doing using `!`, like `assert!(!having_fun())`.""" +[[exercises]] +name = "tests4" +path = "exercises/tests/tests4.rs" +mode = "test" +hint = """ +We expect method `Rectangle::new()` to panic for negative values. +To handle that you need to add special attribute to test function. +You can refer to the docs: https://doc.rust-lang.org/stable/book/ch11-01-writing-tests.html""" + + # STANDARD LIBRARY TYPES [[exercises]] From c4974ac7820784899592a26b4227683bca96bd2b Mon Sep 17 00:00:00 2001 From: poneciak Date: Wed, 5 Apr 2023 13:09:13 +0200 Subject: [PATCH 06/58] added required changes - fixed grammar in hint and added more specific link - added comments in test functions - changed introduction paragraph --- exercises/tests/tests4.rs | 11 ++++++++--- info.toml | 5 +++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/exercises/tests/tests4.rs b/exercises/tests/tests4.rs index 2d8dd130..727dbd7e 100644 --- a/exercises/tests/tests4.rs +++ b/exercises/tests/tests4.rs @@ -1,6 +1,5 @@ // tests4.rs -// Correct the tests to -// Do not change Rectangle::new body +// Make sure that we're testing for the correct conditions! // Execute `rustlings hint tests4` or use the `hint` watch subcommand for a hint. // I AM NOT DONE @@ -11,6 +10,7 @@ struct Rectangle { } impl Rectangle { + // Only change the test functions themselves pub fn new(width: i32, height: i32) -> Self { if width < 0 || height < 0 { panic!("Rectangle width and height cannot be negative!") @@ -25,16 +25,21 @@ mod tests { #[test] fn correct_width_and_height() { - let _rect = Rectangle::new(10, 10); + // This test should check if the rectangle is the size that we pass into its constructor + let rect = Rectangle::new(10, 20); + assert_eq!(???, 10); // check width + assert_eq!(???, 20); // check height } #[test] fn negative_width() { + // This test should check if thread panics when we try to create rectangle with negative width let _rect = Rectangle::new(-10, 10); } #[test] fn negative_height() { + // This test should check if thread panics when we try to create rectangle with negative height let _rect = Rectangle::new(10, -10); } } diff --git a/info.toml b/info.toml index ad06b888..fe79bdee 100644 --- a/info.toml +++ b/info.toml @@ -813,8 +813,9 @@ path = "exercises/tests/tests4.rs" mode = "test" hint = """ We expect method `Rectangle::new()` to panic for negative values. -To handle that you need to add special attribute to test function. -You can refer to the docs: https://doc.rust-lang.org/stable/book/ch11-01-writing-tests.html""" +To handle that you need to add a special attribute to the test function. +You can refer to the docs: +https://doc.rust-lang.org/stable/book/ch11-01-writing-tests.html#checking-for-panics-with-should_panic""" # STANDARD LIBRARY TYPES From 102d7f3d0ec8d9e6b0f4380c9ec199c47cf127f1 Mon Sep 17 00:00:00 2001 From: poneciak Date: Wed, 5 Apr 2023 13:24:14 +0200 Subject: [PATCH 07/58] changed comments in tests also fixed small logical issue in `Rectangle::new()` where u could create rectangle with width or height equals 0 --- exercises/tests/tests4.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/exercises/tests/tests4.rs b/exercises/tests/tests4.rs index 727dbd7e..1f34a2b2 100644 --- a/exercises/tests/tests4.rs +++ b/exercises/tests/tests4.rs @@ -12,7 +12,7 @@ struct Rectangle { impl Rectangle { // Only change the test functions themselves pub fn new(width: i32, height: i32) -> Self { - if width < 0 || height < 0 { + if width <= 0 || height <= 0 { panic!("Rectangle width and height cannot be negative!") } Rectangle {width, height} @@ -33,13 +33,13 @@ mod tests { #[test] fn negative_width() { - // This test should check if thread 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); } #[test] fn negative_height() { - // This test should check if thread 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); } } From af365f444fb63d3f0cc7a86452d89ca6f73e9821 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 5 Apr 2023 13:05:29 +0000 Subject: [PATCH 08/58] docs: update AUTHORS.md [skip ci] --- AUTHORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS.md b/AUTHORS.md index cffd25eb..f39c7642 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -284,6 +284,7 @@ authors. Keogami
Keogami

πŸ“– Alexandre Esse
Alexandre Esse

πŸ–‹ Sagar Vora
Sagar Vora

πŸ–‹ + Kacper Poneta
Kacper Poneta

πŸ–‹ From 63a467af31a8bda072db78c2dc0037a5498baf47 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 5 Apr 2023 13:05:30 +0000 Subject: [PATCH 09/58] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 97cd1b04..bcf84753 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -2001,6 +2001,15 @@ "contributions": [ "content" ] + }, + { + "login": "poneciak57", + "name": "Kacper Poneta", + "avatar_url": "https://avatars.githubusercontent.com/u/94321164?v=4", + "profile": "https://github.com/poneciak57", + "contributions": [ + "content" + ] } ], "contributorsPerLine": 8, From 722c7910e411fb11cab5ada2222d6c52976a2411 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 5 Apr 2023 13:06:58 +0000 Subject: [PATCH 10/58] docs: update AUTHORS.md [skip ci] --- AUTHORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS.md b/AUTHORS.md index f39c7642..e32782e8 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -285,6 +285,7 @@ authors. Alexandre Esse
Alexandre Esse

πŸ–‹ Sagar Vora
Sagar Vora

πŸ–‹ Kacper Poneta
Kacper Poneta

πŸ–‹ + Aaron Suggs
Aaron Suggs

πŸ–‹ From 16ca8715441dabd402dbdf431e117f3c9ad7ff8e Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 5 Apr 2023 13:06:59 +0000 Subject: [PATCH 11/58] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index bcf84753..01576d27 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -2010,6 +2010,15 @@ "contributions": [ "content" ] + }, + { + "login": "ktheory", + "name": "Aaron Suggs", + "avatar_url": "https://avatars.githubusercontent.com/u/975?v=4", + "profile": "https://ktheory.com/", + "contributions": [ + "content" + ] } ], "contributorsPerLine": 8, From c7adaa7d14b66012d10f7e5ad55ee9c3e8615b8b Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 5 Apr 2023 13:09:50 +0000 Subject: [PATCH 12/58] docs: update AUTHORS.md [skip ci] --- AUTHORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS.md b/AUTHORS.md index e32782e8..ed50669b 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -286,6 +286,7 @@ authors. Sagar Vora
Sagar Vora

πŸ–‹ Kacper Poneta
Kacper Poneta

πŸ–‹ Aaron Suggs
Aaron Suggs

πŸ–‹ + Alex
Alex

πŸ–‹ From d544bfcd6ddc3167a5a484b8ea8776d4828642ee Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 5 Apr 2023 13:09:51 +0000 Subject: [PATCH 13/58] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 01576d27..e055aed7 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -2019,6 +2019,15 @@ "contributions": [ "content" ] + }, + { + "login": "alexwh", + "name": "Alex", + "avatar_url": "https://avatars.githubusercontent.com/u/1723612?v=4", + "profile": "https://github.com/alexwh", + "contributions": [ + "content" + ] } ], "contributorsPerLine": 8, From 2f338260632ae65bfd6febf28bde68b26e187b9e Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 5 Apr 2023 13:11:14 +0000 Subject: [PATCH 14/58] docs: update AUTHORS.md [skip ci] --- AUTHORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS.md b/AUTHORS.md index ed50669b..9e757bc2 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -287,6 +287,7 @@ authors. Kacper Poneta
Kacper Poneta

πŸ–‹ Aaron Suggs
Aaron Suggs

πŸ–‹ Alex
Alex

πŸ–‹ + Sebastian TΓΆrnquist
Sebastian TΓΆrnquist

πŸ–‹ From 5de7124eeedbff53a493cbff0e6d4e5b97706c42 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 5 Apr 2023 13:11:15 +0000 Subject: [PATCH 15/58] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index e055aed7..bdcf53c6 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -2028,6 +2028,15 @@ "contributions": [ "content" ] + }, + { + "login": "stornquist", + "name": "Sebastian TΓΆrnquist", + "avatar_url": "https://avatars.githubusercontent.com/u/42915664?v=4", + "profile": "https://github.com/stornquist", + "contributions": [ + "content" + ] } ], "contributorsPerLine": 8, From c74e0bfd188169c15e51dd10501119515dbc220e Mon Sep 17 00:00:00 2001 From: Aaron Wang Date: Fri, 7 Apr 2023 01:56:20 -0400 Subject: [PATCH 16/58] docs: update line numbers in move_semantics2 --- exercises/move_semantics/move_semantics2.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/move_semantics/move_semantics2.rs b/exercises/move_semantics/move_semantics2.rs index 68dbf021..ae76a7aa 100644 --- a/exercises/move_semantics/move_semantics2.rs +++ b/exercises/move_semantics/move_semantics2.rs @@ -1,5 +1,5 @@ // move_semantics2.rs -// Make me compile without changing line 13 or moving line 10! +// Make me compile without changing line 17 or moving line 14! // Execute `rustlings hint move_semantics2` or use the `hint` watch subcommand for a hint. // Expected output: From 8ed2cf7ef5209012f6948b55747a4142939f0930 Mon Sep 17 00:00:00 2001 From: Aaron Wang Date: Mon, 10 Apr 2023 22:36:21 -0400 Subject: [PATCH 17/58] Update move_semantics2.rs --- exercises/move_semantics/move_semantics2.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/move_semantics/move_semantics2.rs b/exercises/move_semantics/move_semantics2.rs index ae76a7aa..93bb82ef 100644 --- a/exercises/move_semantics/move_semantics2.rs +++ b/exercises/move_semantics/move_semantics2.rs @@ -1,5 +1,4 @@ // move_semantics2.rs -// Make me compile without changing line 17 or moving line 14! // Execute `rustlings hint move_semantics2` or use the `hint` watch subcommand for a hint. // Expected output: @@ -11,6 +10,7 @@ fn main() { let vec0 = Vec::new(); + // Do not move the following line! let mut vec1 = fill_vec(vec0); // Do not change the following line! From 352267871cbc30d201c53179da3a31d9f5657d44 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sat, 15 Apr 2023 17:19:16 +0100 Subject: [PATCH 18/58] fix: Added some extra tests to validate iterators5 solution closes: #1387 --- exercises/iterators/iterators5.rs | 53 ++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 8 deletions(-) diff --git a/exercises/iterators/iterators5.rs b/exercises/iterators/iterators5.rs index 87097956..45f0d485 100644 --- a/exercises/iterators/iterators5.rs +++ b/exercises/iterators/iterators5.rs @@ -65,12 +65,27 @@ mod tests { } #[test] - fn count_equals_for() { + fn count_some() { let map = get_map(); - assert_eq!( - count_for(&map, Progress::Complete), - count_iterator(&map, Progress::Complete) - ); + assert_eq!(1, count_iterator(&map, Progress::Some)); + } + + #[test] + fn count_none() { + let map = get_map(); + assert_eq!(2, count_iterator(&map, Progress::None)); + } + + #[test] + fn count_complete_equals_for() { + let map = get_map(); + let progressStates = vec![Progress::Complete, Progress::Some, Progress::None]; + for progressState in progressStates { + assert_eq!( + count_for(&map, progressState), + count_iterator(&map, progressState) + ); + } } #[test] @@ -83,14 +98,36 @@ mod tests { } #[test] - fn count_collection_equals_for() { + fn count_collection_some() { let collection = get_vec_map(); assert_eq!( - count_collection_for(&collection, Progress::Complete), - count_collection_iterator(&collection, Progress::Complete) + 1, + count_collection_iterator(&collection, Progress::Some) ); } + #[test] + fn count_collection_none() { + let collection = get_vec_map(); + assert_eq!( + 4, + count_collection_iterator(&collection, Progress::None) + ); + } + + #[test] + fn count_collection_equals_for() { + let progressStates = vec![Progress::Complete, Progress::Some, Progress::None]; + let collection = get_vec_map(); + + for progressState in progressStates { + assert_eq!( + count_collection_for(&collection, progressState), + count_collection_iterator(&collection, progressState) + ); + } + } + fn get_map() -> HashMap { use Progress::*; From a4a5691a7b3fac8201cf2965d94267da12bae47f Mon Sep 17 00:00:00 2001 From: Sebastian LaVine Date: Sun, 16 Apr 2023 21:44:08 -0400 Subject: [PATCH 19/58] feat: Add "!" command to `rustlings watch` --- src/main.rs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/main.rs b/src/main.rs index 704398e5..793b826d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -298,13 +298,21 @@ fn spawn_watch_shell( println!("Bye!"); } else if input.eq("help") { println!("Commands available to you in watch mode:"); - println!(" hint - prints the current exercise's hint"); - println!(" clear - clears the screen"); - println!(" quit - quits watch mode"); - println!(" help - displays this help message"); + println!(" hint - prints the current exercise's hint"); + println!(" clear - clears the screen"); + println!(" quit - quits watch mode"); + println!(" ! - executes a command, like `!rustc --explain E0381`"); + println!(" help - displays this help message"); println!(); println!("Watch mode automatically re-evaluates the current exercise"); println!("when you edit a file's contents.") + } else if let Some(cmd) = input.strip_prefix('!') { + let parts: Vec<&str> = cmd.split_whitespace().collect(); + if parts.is_empty() { + println!("no command provided"); + } else if let Err(e) = Command::new(parts[0]).args(&parts[1..]).status() { + println!("failed to execute command `{}`: {}", cmd, e); + } } else { println!("unknown command: {input}"); } From 4944488287ca28bb73b067c3b0321adb6fb010ae Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 18 Apr 2023 15:51:24 +0000 Subject: [PATCH 20/58] docs: update AUTHORS.md [skip ci] --- AUTHORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS.md b/AUTHORS.md index 9e757bc2..f5accd79 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -288,6 +288,7 @@ authors. Aaron Suggs
Aaron Suggs

πŸ–‹ Alex
Alex

πŸ–‹ Sebastian TΓΆrnquist
Sebastian TΓΆrnquist

πŸ–‹ + Sebastian LaVine
Sebastian LaVine

πŸ’» From 6209e7004e24492776edc5408260707949e6ffee Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 18 Apr 2023 15:51:25 +0000 Subject: [PATCH 21/58] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index bdcf53c6..9c39e5ec 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -2037,6 +2037,15 @@ "contributions": [ "content" ] + }, + { + "login": "smlavine", + "name": "Sebastian LaVine", + "avatar_url": "https://avatars.githubusercontent.com/u/33563640?v=4", + "profile": "http://smlavine.com", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 8, From 319a8253ba727d09a1c52c7d22b4e089137ecff9 Mon Sep 17 00:00:00 2001 From: Alan Gerber Date: Thu, 20 Apr 2023 12:15:31 -0400 Subject: [PATCH 22/58] fix(move_semantics2): fix line number comment Commit fef8314 added three lines of comments, which left the line numbers expected to stay unchanged mentioned on line 2 out of date. --- exercises/move_semantics/move_semantics2.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/move_semantics/move_semantics2.rs b/exercises/move_semantics/move_semantics2.rs index 68dbf021..ae76a7aa 100644 --- a/exercises/move_semantics/move_semantics2.rs +++ b/exercises/move_semantics/move_semantics2.rs @@ -1,5 +1,5 @@ // move_semantics2.rs -// Make me compile without changing line 13 or moving line 10! +// Make me compile without changing line 17 or moving line 14! // Execute `rustlings hint move_semantics2` or use the `hint` watch subcommand for a hint. // Expected output: From 836134202ef505e03e8177565e512059488aded2 Mon Sep 17 00:00:00 2001 From: lionel-rowe Date: Fri, 21 Apr 2023 06:05:25 +0100 Subject: [PATCH 23/58] feat(options2): better tests for layered_option The existing test can be solved with the following: ```rs while let Some(integer) = optional_integers.pop() { assert_eq!(integer.unwrap(), range); ``` Similarly with `expect(...)`, `unwrap_or(0)`, `unwrap_or_default()`, etc. However, none of these solutions use the learning point of stacking `Option`s. The updated test can _only_ be solved by stacking `Option`s: ```rs while let Some(Some(integer)) = optional_integers.pop() { assert_eq!(integer, cursor); ``` With the updated test, using `unwrap` or `expect` will panic when it hits the `None` value, and using `unwrap_or` or `unwrap_or_default` will cause the final `assert_eq!(cursor, 0)` to panic. --- exercises/options/options2.rs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/exercises/options/options2.rs b/exercises/options/options2.rs index 4e36443f..337c4261 100644 --- a/exercises/options/options2.rs +++ b/exercises/options/options2.rs @@ -18,17 +18,22 @@ mod tests { #[test] fn layered_option() { - let mut range = 10; - let mut optional_integers: Vec> = Vec::new(); - for i in 0..(range + 1) { + let range = 10; + let mut optional_integers: Vec> = vec![None]; + + for i in 1..(range + 1) { optional_integers.push(Some(i)); } + let mut cursor = range; + // TODO: make this a while let statement - remember that vector.pop also adds another layer of Option - // You can stack `Option`'s into while let and if let + // You can stack `Option`s into while let and if let integer = optional_integers.pop() { - assert_eq!(integer, range); - range -= 1; + assert_eq!(integer, cursor); + cursor -= 1; } + + assert_eq!(cursor, 0); } } From e2da663628f61f19066cd92b005bae3adc8521d8 Mon Sep 17 00:00:00 2001 From: deedy5 <65482418+deedy5@users.noreply.github.com> Date: Fri, 21 Apr 2023 15:51:52 +0000 Subject: [PATCH 24/58] Update info.toml modules2.rs: add more information to hint --- info.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/info.toml b/info.toml index 28f9bb31..ac04fc7d 100644 --- a/info.toml +++ b/info.toml @@ -478,7 +478,8 @@ hint = """ The delicious_snacks module is trying to present an external interface that is different than its internal structure (the `fruits` and `veggies` modules and associated constants). Complete the `use` statements to fit the uses in main and -find the one keyword missing for both constants.""" +find the one keyword missing for both constants. +Learn more at https://doc.rust-lang.org/book/ch07-04-bringing-paths-into-scope-with-the-use-keyword.html#re-exporting-names-with-pub-use""" [[exercises]] name = "modules3" From 065cd0170e46fbdf0f74aee4708c4e3a200ab6ce Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Sat, 22 Apr 2023 13:48:41 +0000 Subject: [PATCH 25/58] docs: update AUTHORS.md [skip ci] --- AUTHORS.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/AUTHORS.md b/AUTHORS.md index f5accd79..0f45c38f 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -290,6 +290,9 @@ authors. Sebastian TΓΆrnquist
Sebastian TΓΆrnquist

πŸ–‹ Sebastian LaVine
Sebastian LaVine

πŸ’» + + Alan Gerber
Alan Gerber

πŸ–‹ + From 545a7262523cfe3074e91314ad621d84e48d81c1 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Sat, 22 Apr 2023 13:48:42 +0000 Subject: [PATCH 26/58] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 9c39e5ec..8dd0d928 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -2046,6 +2046,15 @@ "contributions": [ "code" ] + }, + { + "login": "akgerber", + "name": "Alan Gerber", + "avatar_url": "https://avatars.githubusercontent.com/u/201313?v=4", + "profile": "http://www.alangerber.us", + "contributions": [ + "content" + ] } ], "contributorsPerLine": 8, From c4627e7112f38a74e677f358bf5eafc7214c5a4f Mon Sep 17 00:00:00 2001 From: PiqqiDesigns Date: Thu, 27 Apr 2023 15:49:40 -0700 Subject: [PATCH 27/58] chore: clarified cow owned_no_mutation comments --- exercises/smart_pointers/cow1.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/exercises/smart_pointers/cow1.rs b/exercises/smart_pointers/cow1.rs index 885138a7..bc5b28e5 100644 --- a/exercises/smart_pointers/cow1.rs +++ b/exercises/smart_pointers/cow1.rs @@ -52,7 +52,8 @@ mod tests { fn owned_no_mutation() -> Result<(), &'static str> { // We can also pass `slice` without `&` so Cow owns it directly. // In this case no mutation occurs and thus also no clone, - // but the result is still owned because it always was. + // but the result is still owned because it was never borrowed + // or mutated. let slice = vec![0, 1, 2]; let mut input = Cow::from(slice); match abs_all(&mut input) { From 72d0c53b33e45cc55a5eb0c82119b7e393c0c59b Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Fri, 28 Apr 2023 08:40:17 +0000 Subject: [PATCH 28/58] docs: update AUTHORS.md [skip ci] --- AUTHORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS.md b/AUTHORS.md index 0f45c38f..8e4d0fab 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -292,6 +292,7 @@ authors. Alan Gerber
Alan Gerber

πŸ–‹ + Eric
Eric

πŸ–‹ From eb4079c674640b4fc307d5dca7a23dcef33129f2 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Fri, 28 Apr 2023 08:40:18 +0000 Subject: [PATCH 29/58] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 8dd0d928..a973b2d7 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -2055,6 +2055,15 @@ "contributions": [ "content" ] + }, + { + "login": "esotuvaka", + "name": "Eric", + "avatar_url": "https://avatars.githubusercontent.com/u/104941850?v=4", + "profile": "http://esotuvaka.github.io", + "contributions": [ + "content" + ] } ], "contributorsPerLine": 8, From 5d3696a9e6bc6251f0c03d17d0d6a7a10ee09115 Mon Sep 17 00:00:00 2001 From: Romain Bayle <5014@holbertonstudents.com> Date: Mon, 1 May 2023 02:49:19 +0200 Subject: [PATCH 30/58] feat(cli): added success-hints option for the rustlings command closes #1373 --- src/main.rs | 14 +++++++++----- src/verify.rs | 32 +++++++++++++++++++------------- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/src/main.rs b/src/main.rs index 793b826d..eaa365a4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -37,6 +37,9 @@ struct Args { /// show the executable version #[argh(switch, short = 'v')] version: bool, + /// show hints on success + #[argh(switch)] + success_hints: bool, #[argh(subcommand)] nested: Option, } @@ -148,6 +151,7 @@ fn main() { let toml_str = &fs::read_to_string("info.toml").unwrap(); let exercises = toml::from_str::(toml_str).unwrap().exercises; let verbose = args.nocapture; + let success_hints = args.success_hints; let command = args.nested.unwrap_or_else(|| { println!("{DEFAULT_OUT}\n"); @@ -229,7 +233,7 @@ fn main() { } Subcommands::Verify(_subargs) => { - verify(&exercises, (0, exercises.len()), verbose) + verify(&exercises, (0, exercises.len()), verbose, success_hints) .unwrap_or_else(|_| std::process::exit(1)); } @@ -252,7 +256,7 @@ fn main() { } } - Subcommands::Watch(_subargs) => match watch(&exercises, verbose) { + Subcommands::Watch(_subargs) => match watch(&exercises, verbose, success_hints) { Err(e) => { println!( "Error: Could not watch your progress. Error message was {:?}.", @@ -348,7 +352,7 @@ enum WatchStatus { Unfinished, } -fn watch(exercises: &[Exercise], verbose: bool) -> notify::Result { +fn watch(exercises: &[Exercise], verbose: bool, success_hints: bool) -> notify::Result { /* Clears the terminal with an ANSI escape code. Works in UNIX and newer Windows terminals. */ fn clear_screen() { @@ -364,7 +368,7 @@ fn watch(exercises: &[Exercise], verbose: bool) -> notify::Result { clear_screen(); let to_owned_hint = |t: &Exercise| t.hint.to_owned(); - let failed_exercise_hint = match verify(exercises.iter(), (0, exercises.len()), verbose) { + let failed_exercise_hint = match verify(exercises.iter(), (0, exercises.len()), verbose, success_hints) { Ok(_) => return Ok(WatchStatus::Finished), Err(exercise) => Arc::new(Mutex::new(Some(to_owned_hint(exercise)))), }; @@ -386,7 +390,7 @@ fn watch(exercises: &[Exercise], verbose: bool) -> notify::Result { ); let num_done = exercises.iter().filter(|e| e.looks_done()).count(); clear_screen(); - match verify(pending_exercises, (num_done, exercises.len()), verbose) { + match verify(pending_exercises, (num_done, exercises.len()), verbose, success_hints) { Ok(_) => return Ok(WatchStatus::Finished), Err(exercise) => { let mut failed_exercise_hint = failed_exercise_hint.lock().unwrap(); diff --git a/src/verify.rs b/src/verify.rs index 68ba6cef..f3f3b564 100644 --- a/src/verify.rs +++ b/src/verify.rs @@ -12,6 +12,7 @@ pub fn verify<'a>( exercises: impl IntoIterator, progress: (usize, usize), verbose: bool, + success_hints: bool, ) -> Result<(), &'a Exercise> { let (num_done, total) = progress; let bar = ProgressBar::new(total as u64); @@ -25,9 +26,9 @@ pub fn verify<'a>( for exercise in exercises { let compile_result = match exercise.mode { - Mode::Test => compile_and_test(exercise, RunMode::Interactive, verbose), - Mode::Compile => compile_and_run_interactively(exercise), - Mode::Clippy => compile_only(exercise), + Mode::Test => compile_and_test(exercise, RunMode::Interactive, verbose, success_hints), + Mode::Compile => compile_and_run_interactively(exercise, success_hints), + Mode::Clippy => compile_only(exercise, success_hints), }; if !compile_result.unwrap_or(false) { return Err(exercise); @@ -46,12 +47,12 @@ enum RunMode { // Compile and run the resulting test harness of the given Exercise pub fn test(exercise: &Exercise, verbose: bool) -> Result<(), ()> { - compile_and_test(exercise, RunMode::NonInteractive, verbose)?; + compile_and_test(exercise, RunMode::NonInteractive, verbose, false)?; Ok(()) } // Invoke the rust compiler without running the resulting binary -fn compile_only(exercise: &Exercise) -> Result { +fn compile_only(exercise: &Exercise, success_hints: bool) -> Result { let progress_bar = ProgressBar::new_spinner(); progress_bar.set_message(format!("Compiling {exercise}...")); progress_bar.enable_steady_tick(100); @@ -59,11 +60,11 @@ fn compile_only(exercise: &Exercise) -> Result { let _ = compile(exercise, &progress_bar)?; progress_bar.finish_and_clear(); - Ok(prompt_for_completion(exercise, None)) + Ok(prompt_for_completion(exercise, None, success_hints)) } // Compile the given Exercise and run the resulting binary in an interactive mode -fn compile_and_run_interactively(exercise: &Exercise) -> Result { +fn compile_and_run_interactively(exercise: &Exercise, success_hints: bool) -> Result { let progress_bar = ProgressBar::new_spinner(); progress_bar.set_message(format!("Compiling {exercise}...")); progress_bar.enable_steady_tick(100); @@ -84,12 +85,12 @@ fn compile_and_run_interactively(exercise: &Exercise) -> Result { } }; - Ok(prompt_for_completion(exercise, Some(output.stdout))) + Ok(prompt_for_completion(exercise, Some(output.stdout), success_hints)) } // Compile the given Exercise as a test harness and display // the output if verbose is set to true -fn compile_and_test(exercise: &Exercise, run_mode: RunMode, verbose: bool) -> Result { +fn compile_and_test(exercise: &Exercise, run_mode: RunMode, verbose: bool, success_hints: bool) -> Result { let progress_bar = ProgressBar::new_spinner(); progress_bar.set_message(format!("Testing {exercise}...")); progress_bar.enable_steady_tick(100); @@ -104,7 +105,7 @@ fn compile_and_test(exercise: &Exercise, run_mode: RunMode, verbose: bool) -> Re println!("{}", output.stdout); } if let RunMode::Interactive = run_mode { - Ok(prompt_for_completion(exercise, None)) + Ok(prompt_for_completion(exercise, None, success_hints)) } else { Ok(true) } @@ -142,12 +143,11 @@ fn compile<'a, 'b>( } } -fn prompt_for_completion(exercise: &Exercise, prompt_output: Option) -> bool { +fn prompt_for_completion(exercise: &Exercise, prompt_output: Option, success_hints: bool) -> bool { let context = match exercise.state() { State::Done => return true, State::Pending(context) => context, }; - match exercise.mode { Mode::Compile => success!("Successfully ran {}!", exercise), Mode::Test => success!("Successfully tested {}!", exercise), @@ -167,7 +167,6 @@ fn prompt_for_completion(exercise: &Exercise, prompt_output: Option) -> Mode::Test => "The code is compiling, and the tests pass!", Mode::Clippy => clippy_success_msg, }; - println!(); if no_emoji { println!("~*~ {success_msg} ~*~") @@ -183,6 +182,13 @@ fn prompt_for_completion(exercise: &Exercise, prompt_output: Option) -> println!("{}", separator()); println!(); } + if success_hints { + println!("Hints:"); + println!("{}", separator()); + println!("{}", exercise.hint); + println!("{}", separator()); + println!(); + } println!("You can keep working on this exercise,"); println!( From e631f3c78bf3f09955353778c8aa377085653d7a Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 2 May 2023 11:15:48 +0000 Subject: [PATCH 31/58] docs: update AUTHORS.md [skip ci] --- AUTHORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS.md b/AUTHORS.md index 8e4d0fab..164370ab 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -293,6 +293,7 @@ authors. Alan Gerber
Alan Gerber

πŸ–‹ Eric
Eric

πŸ–‹ + Aaron Wang
Aaron Wang

πŸ–‹ From 583925c085308645504b30a323d66b8edf6f798a Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 2 May 2023 11:15:49 +0000 Subject: [PATCH 32/58] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index a973b2d7..0e1b6373 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -2064,6 +2064,15 @@ "contributions": [ "content" ] + }, + { + "login": "az0977776", + "name": "Aaron Wang", + "avatar_url": "https://avatars.githubusercontent.com/u/9172038?v=4", + "profile": "https://github.com/az0977776", + "contributions": [ + "content" + ] } ], "contributorsPerLine": 8, From c44e3025f9a5af4b4a7999edddd76b7f7863328a Mon Sep 17 00:00:00 2001 From: Romain Bayle <5014@holbertonstudents.com> Date: Tue, 2 May 2023 22:46:41 +0200 Subject: [PATCH 33/58] option success_hints added to the struct Watchargs instead of Args --- src/main.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main.rs b/src/main.rs index eaa365a4..74e8161b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -37,9 +37,6 @@ struct Args { /// show the executable version #[argh(switch, short = 'v')] version: bool, - /// show hints on success - #[argh(switch)] - success_hints: bool, #[argh(subcommand)] nested: Option, } @@ -64,7 +61,11 @@ struct VerifyArgs {} #[derive(FromArgs, PartialEq, Debug)] #[argh(subcommand, name = "watch")] /// Reruns `verify` when files were edited -struct WatchArgs {} +struct WatchArgs { + /// show hints on success + #[argh(switch)] + success_hints: bool, +} #[derive(FromArgs, PartialEq, Debug)] #[argh(subcommand, name = "run")] @@ -151,7 +152,6 @@ fn main() { let toml_str = &fs::read_to_string("info.toml").unwrap(); let exercises = toml::from_str::(toml_str).unwrap().exercises; let verbose = args.nocapture; - let success_hints = args.success_hints; let command = args.nested.unwrap_or_else(|| { println!("{DEFAULT_OUT}\n"); @@ -233,7 +233,7 @@ fn main() { } Subcommands::Verify(_subargs) => { - verify(&exercises, (0, exercises.len()), verbose, success_hints) + verify(&exercises, (0, exercises.len()), verbose, false) .unwrap_or_else(|_| std::process::exit(1)); } @@ -256,7 +256,7 @@ fn main() { } } - Subcommands::Watch(_subargs) => match watch(&exercises, verbose, success_hints) { + Subcommands::Watch(_subargs) => match watch(&exercises, verbose, _subargs.success_hints) { Err(e) => { println!( "Error: Could not watch your progress. Error message was {:?}.", From 3ecb47ff2cf7e5b6b6aa115fba02228896654b60 Mon Sep 17 00:00:00 2001 From: Noah May Date: Tue, 9 May 2023 15:13:18 -0500 Subject: [PATCH 34/58] fix(options3): panic when not matching to avoid false positives Closes #1503 --- exercises/options/options3.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/options/options3.rs b/exercises/options/options3.rs index 3f995c52..3ed76eeb 100644 --- a/exercises/options/options3.rs +++ b/exercises/options/options3.rs @@ -13,7 +13,7 @@ fn main() { match y { Some(p) => println!("Co-ordinates are {},{} ", p.x, p.y), - _ => println!("no match"), + _ => panic!("no match!"), } y; // Fix without deleting this line. } From 70da26f649adcb7ea583db36a07bc8f285f3f5c3 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 10 May 2023 08:49:44 +0000 Subject: [PATCH 35/58] docs: update AUTHORS.md [skip ci] --- AUTHORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS.md b/AUTHORS.md index 164370ab..f1e43376 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -294,6 +294,7 @@ authors. Alan Gerber
Alan Gerber

πŸ–‹ Eric
Eric

πŸ–‹ Aaron Wang
Aaron Wang

πŸ–‹ + Noah
Noah

πŸ–‹ From 0d252636be6675e24475d821a953cdaf5f1e0f45 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 10 May 2023 08:49:45 +0000 Subject: [PATCH 36/58] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 0e1b6373..47589247 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -2073,6 +2073,15 @@ "contributions": [ "content" ] + }, + { + "login": "nmay231", + "name": "Noah", + "avatar_url": "https://avatars.githubusercontent.com/u/35386821?v=4", + "profile": "https://github.com/nmay231", + "contributions": [ + "content" + ] } ], "contributorsPerLine": 8, From 70cf7698acbde43025a23d0199057485d8d75ade Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 17 May 2023 13:54:39 +0000 Subject: [PATCH 37/58] docs: update AUTHORS.md [skip ci] --- AUTHORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS.md b/AUTHORS.md index f1e43376..ed45690c 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -295,6 +295,7 @@ authors. Eric
Eric

πŸ–‹ Aaron Wang
Aaron Wang

πŸ–‹ Noah
Noah

πŸ–‹ + rb5014
rb5014

πŸ–‹ From c5fe42089d5fe6a15f1e1a18f1a4f8d612f2d3c0 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 17 May 2023 13:54:40 +0000 Subject: [PATCH 38/58] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 47589247..654d2d93 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -2082,6 +2082,15 @@ "contributions": [ "content" ] + }, + { + "login": "rb5014", + "name": "rb5014", + "avatar_url": "https://avatars.githubusercontent.com/u/105397317?v=4", + "profile": "https://github.com/rb5014", + "contributions": [ + "content" + ] } ], "contributorsPerLine": 8, From 94c6131c59456c70302ee5c3d39114786533daf4 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 17 May 2023 13:55:28 +0000 Subject: [PATCH 39/58] docs: update AUTHORS.md [skip ci] --- AUTHORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS.md b/AUTHORS.md index ed45690c..8a24e68f 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -296,6 +296,7 @@ authors. Aaron Wang
Aaron Wang

πŸ–‹ Noah
Noah

πŸ–‹ rb5014
rb5014

πŸ–‹ + deedy5
deedy5

πŸ–‹ From 6abff3954921aba490b9f135c701ccb5f26595c5 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 17 May 2023 13:55:29 +0000 Subject: [PATCH 40/58] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 654d2d93..35684e39 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -2091,6 +2091,15 @@ "contributions": [ "content" ] + }, + { + "login": "deedy5", + "name": "deedy5", + "avatar_url": "https://avatars.githubusercontent.com/u/65482418?v=4", + "profile": "https://github.com/deedy5", + "contributions": [ + "content" + ] } ], "contributorsPerLine": 8, From 58cbdd71b64ad8d32d192e56cedd563ebca6fd5b Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 17 May 2023 13:57:10 +0000 Subject: [PATCH 41/58] docs: update AUTHORS.md [skip ci] --- AUTHORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS.md b/AUTHORS.md index 8a24e68f..c1cc60c2 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -297,6 +297,7 @@ authors. Noah
Noah

πŸ–‹ rb5014
rb5014

πŸ–‹ deedy5
deedy5

πŸ–‹ + lionel-rowe
lionel-rowe

πŸ–‹ From eeb439eaf9e164307dd2533d5ef082f740f53af3 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 17 May 2023 13:57:11 +0000 Subject: [PATCH 42/58] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 35684e39..56c5e028 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -2100,6 +2100,15 @@ "contributions": [ "content" ] + }, + { + "login": "lionel-rowe", + "name": "lionel-rowe", + "avatar_url": "https://avatars.githubusercontent.com/u/26078826?v=4", + "profile": "https://github.com/lionel-rowe", + "contributions": [ + "content" + ] } ], "contributorsPerLine": 8, From a6f99645c6cb1b5493e1fbf16576ab5c0f1dd88c Mon Sep 17 00:00:00 2001 From: liv Date: Wed, 17 May 2023 16:02:39 +0200 Subject: [PATCH 43/58] chore: rustfmt --- exercises/iterators/iterators5.rs | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/exercises/iterators/iterators5.rs b/exercises/iterators/iterators5.rs index 45f0d485..dcf0742d 100644 --- a/exercises/iterators/iterators5.rs +++ b/exercises/iterators/iterators5.rs @@ -77,7 +77,7 @@ mod tests { } #[test] - fn count_complete_equals_for() { + fn count_complete_equals_for() { let map = get_map(); let progressStates = vec![Progress::Complete, Progress::Some, Progress::None]; for progressState in progressStates { @@ -100,19 +100,13 @@ mod tests { #[test] fn count_collection_some() { let collection = get_vec_map(); - assert_eq!( - 1, - count_collection_iterator(&collection, Progress::Some) - ); + assert_eq!(1, count_collection_iterator(&collection, Progress::Some)); } #[test] fn count_collection_none() { let collection = get_vec_map(); - assert_eq!( - 4, - count_collection_iterator(&collection, Progress::None) - ); + assert_eq!(4, count_collection_iterator(&collection, Progress::None)); } #[test] From 9508e9791495f6e6f4c64b330a6cbba37241fafc Mon Sep 17 00:00:00 2001 From: liv Date: Wed, 17 May 2023 16:14:10 +0200 Subject: [PATCH 44/58] feat: write absolute root module paths for lsp --- src/project.rs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/project.rs b/src/project.rs index 6e483504..7865d927 100644 --- a/src/project.rs +++ b/src/project.rs @@ -1,8 +1,9 @@ use glob::glob; use serde::{Deserialize, Serialize}; -use std::env; use std::error::Error; +use std::path::PathBuf; use std::process::Command; +use std::{env, fs}; /// Contains the structure of resulting rust-project.json file /// and functions to build the data required to create the file @@ -38,11 +39,12 @@ impl RustAnalyzerProject { } /// If path contains .rs extension, add a crate to `rust-project.json` - fn path_to_json(&mut self, path: String) { - if let Some((_, ext)) = path.split_once('.') { + fn path_to_json(&mut self, path: PathBuf) -> Result<(), Box> { + if let Some(ext) = path.extension() { if ext == "rs" { + let abspath = fs::canonicalize(path)?; self.crates.push(Crate { - root_module: path, + root_module: abspath.display().to_string(), edition: "2021".to_string(), deps: Vec::new(), // This allows rust_analyzer to work inside #[test] blocks @@ -50,15 +52,16 @@ impl RustAnalyzerProject { }) } } + + Ok(()) } /// Parse the exercises folder for .rs files, any matches will create /// a new `crate` in rust-project.json which allows rust-analyzer to /// treat it like a normal binary pub fn exercises_to_json(&mut self) -> Result<(), Box> { - for e in glob("./exercises/**/*")? { - let path = e?.to_string_lossy().to_string(); - self.path_to_json(path); + for path in glob("./exercises/**/*")? { + self.path_to_json(path?)?; } Ok(()) } From af52fce275ba26b653026fffc5c09a73c7ba5846 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 17 May 2023 14:14:43 +0000 Subject: [PATCH 45/58] docs: update AUTHORS.md [skip ci] --- AUTHORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS.md b/AUTHORS.md index c1cc60c2..a27c60e9 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -298,6 +298,7 @@ authors. rb5014
rb5014

πŸ–‹ deedy5
deedy5

πŸ–‹ lionel-rowe
lionel-rowe

πŸ–‹ + Ben
Ben

πŸ–‹ From ab61a0d5c7efb8cc4856587f5354fb2f9024a40a Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 17 May 2023 14:14:44 +0000 Subject: [PATCH 46/58] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 56c5e028..1b9678e0 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -2109,6 +2109,15 @@ "contributions": [ "content" ] + }, + { + "login": "Ben2917", + "name": "Ben", + "avatar_url": "https://avatars.githubusercontent.com/u/10279994?v=4", + "profile": "https://github.com/Ben2917", + "contributions": [ + "content" + ] } ], "contributorsPerLine": 8, From f452fd7bb0118d8e56848ec9e3f5e6e733be6316 Mon Sep 17 00:00:00 2001 From: liv Date: Wed, 17 May 2023 16:30:22 +0200 Subject: [PATCH 47/58] release: 5.5.0 --- CHANGELOG.md | 35 +++++++++++++++++++++++++++++++++++ Cargo.lock | 2 +- Cargo.toml | 2 +- README.md | 8 ++++---- flake.nix | 2 +- src/main.rs | 22 ++++++++++++++++++---- 6 files changed, 60 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c14e7d7..d4d64406 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,38 @@ + +## 5.5.0 (2023-05-17) + +#### Added + +- `strings2`: Added a reference to the book chapter for reference conversion +- `lifetimes`: Added a link to the lifetimekata project +- Added a new `tests4` exercises, which teaches about testing for panics +- Added a `!` prefix command to watch mode that runs an external command +- Added a `--success-hints` option to watch mode that shows hints on exercise success + +#### Changed + +- `vecs2`: Renamed iterator variable bindings for clarify +- `lifetimes`: Changed order of book references +- `hashmaps2`: Clarified instructions in the todo block +- Moved lifetime exercises before test exercises (via the recommended book ordering) +- `options2`: Improved tests for layering options +- `modules2`: Added more information to the hint + +#### Fixed + +- `errors2`: Corrected a comment wording +- `iterators2`: Fixed a spelling mistake in the hint text +- `variables`: Wrapped the mut keyword with backticks for readability +- `move_semantics2`: Removed references to line numbers +- `cow1`: Clarified the `owned_no_mutation` comments +- `options3`: Changed exercise to panic when no match is found +- `rustlings lsp` now generates absolute paths, which should fix VSCode `rust-analyzer` usage on Windows + +#### Housekeeping + +- Added a markdown linter to run on GitHub actions +- Split quick installation section into two code blocks + ## 5.4.1 (2023-03-10) diff --git a/Cargo.lock b/Cargo.lock index 192a4ac0..16f771c7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -441,7 +441,7 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "rustlings" -version = "5.4.1" +version = "5.5.0" dependencies = [ "argh", "assert_cmd", diff --git a/Cargo.toml b/Cargo.toml index d22816ca..e603bbf0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rustlings" -version = "5.4.1" +version = "5.5.0" authors = [ "Liv ", "Carol (Nichols || Goulding) ", diff --git a/README.md b/README.md index be470fdb..92daa332 100644 --- a/README.md +++ b/README.md @@ -36,8 +36,8 @@ This will install Rustlings and give you access to the `rustlings` command. Run 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.4.1) -git clone -b 5.4.1 --depth 1 https://github.com/rust-lang/rustlings +# find out the latest version at https://github.com/rust-lang/rustlings/releases/latest (on edit 5.5.0) +git clone -b 5.5.0 --depth 1 https://github.com/rust-lang/rustlings cd rustlings # if nix version > 2.3 nix develop @@ -74,8 +74,8 @@ If you get a permission denied message, you might have to exclude the directory 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.4.1) -git clone -b 5.4.1 --depth 1 https://github.com/rust-lang/rustlings +# find out the latest version at https://github.com/rust-lang/rustlings/releases/latest (on edit 5.5.0) +git clone -b 5.5.0 --depth 1 https://github.com/rust-lang/rustlings cd rustlings cargo install --force --path . ``` diff --git a/flake.nix b/flake.nix index 5815a920..c8749197 100644 --- a/flake.nix +++ b/flake.nix @@ -22,7 +22,7 @@ rustlings = pkgs.rustPlatform.buildRustPackage { name = "rustlings"; - version = "5.4.1"; + version = "5.5.0"; buildInputs = cargoBuildInputs; diff --git a/src/main.rs b/src/main.rs index 74e8161b..feb673da 100644 --- a/src/main.rs +++ b/src/main.rs @@ -26,7 +26,7 @@ mod run; mod verify; // In sync with crate version -const VERSION: &str = "5.4.1"; +const VERSION: &str = "5.5.0"; #[derive(FromArgs, PartialEq, Debug)] /// Rustlings is a collection of small exercises to get you used to writing and reading Rust code @@ -352,7 +352,11 @@ enum WatchStatus { Unfinished, } -fn watch(exercises: &[Exercise], verbose: bool, success_hints: bool) -> notify::Result { +fn watch( + exercises: &[Exercise], + verbose: bool, + success_hints: bool, +) -> notify::Result { /* Clears the terminal with an ANSI escape code. Works in UNIX and newer Windows terminals. */ fn clear_screen() { @@ -368,7 +372,12 @@ fn watch(exercises: &[Exercise], verbose: bool, success_hints: bool) -> notify:: clear_screen(); let to_owned_hint = |t: &Exercise| t.hint.to_owned(); - let failed_exercise_hint = match verify(exercises.iter(), (0, exercises.len()), verbose, success_hints) { + let failed_exercise_hint = match verify( + exercises.iter(), + (0, exercises.len()), + verbose, + success_hints, + ) { Ok(_) => return Ok(WatchStatus::Finished), Err(exercise) => Arc::new(Mutex::new(Some(to_owned_hint(exercise)))), }; @@ -390,7 +399,12 @@ fn watch(exercises: &[Exercise], verbose: bool, success_hints: bool) -> notify:: ); let num_done = exercises.iter().filter(|e| e.looks_done()).count(); clear_screen(); - match verify(pending_exercises, (num_done, exercises.len()), verbose, success_hints) { + match verify( + pending_exercises, + (num_done, exercises.len()), + verbose, + success_hints, + ) { Ok(_) => return Ok(WatchStatus::Finished), Err(exercise) => { let mut failed_exercise_hint = failed_exercise_hint.lock().unwrap(); From 19cee732094c59669f29ce941ad87f5a90af6bf8 Mon Sep 17 00:00:00 2001 From: liv Date: Wed, 17 May 2023 16:56:01 +0200 Subject: [PATCH 48/58] chore: set up oranda Sets up oranda so we can get nice website things for free. Some caveats we have right now: - Absolutely manual, I have to do `oranda build` and the deploy manually right now - I had to pop the Readme into a new Markdown file because the first header in there was looking very strange --- .gitignore | 4 ++ Cargo.toml | 1 + oranda.json | 11 ++++ website.md | 176 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 192 insertions(+) create mode 100644 oranda.json create mode 100644 website.md diff --git a/.gitignore b/.gitignore index c14f9227..88bf2b6c 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,7 @@ rust-project.json !.vscode/extensions.json *.iml *.o +public/ + +# Local Netlify folder +.netlify diff --git a/Cargo.toml b/Cargo.toml index e603bbf0..498bbf9b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,6 @@ [package] name = "rustlings" +description = "Small exercises to get you used to reading and writing Rust code!" version = "5.5.0" authors = [ "Liv ", diff --git a/oranda.json b/oranda.json new file mode 100644 index 00000000..503653a4 --- /dev/null +++ b/oranda.json @@ -0,0 +1,11 @@ +{ + "homepage": "https://rustlings.cool", + "readme_path": "website.md", + "repository": "https://github.com/rust-lang/rustlings", + "analytics": { + "plausible": { + "domain": "rustlings.cool" + } + }, + "changelog": true +} diff --git a/website.md b/website.md new file mode 100644 index 00000000..92bedc8c --- /dev/null +++ b/website.md @@ -0,0 +1,176 @@ +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! + +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.5.0) +git clone -b 5.5.0 --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.5.0) +git clone -b 5.5.0 --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/`. 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](./CONTRIBUTING.md). + +Development-focused discussion about Rustlings happens in the [**rustlings** stream](https://rust-lang.zulipchat.com/#narrow/stream/334454-rustlings) +on the [Rust Project Zulip](https://rust-lang.zulipchat.com). Feel free to start a new thread there +if you have ideas or suggestions! + +## Contributors ✨ + +Thanks goes to the wonderful people listed in [AUTHORS.md](./AUTHORS.md) πŸŽ‰ From 0667ee7c4d2af44c98aff8db96887ddf40055c49 Mon Sep 17 00:00:00 2001 From: liv Date: Wed, 17 May 2023 17:11:49 +0200 Subject: [PATCH 49/58] fix: add oranda-hide class to readme --- README.md | 4 ++ oranda.json | 1 - website.md | 176 ---------------------------------------------------- 3 files changed, 4 insertions(+), 177 deletions(-) delete mode 100644 website.md diff --git a/README.md b/README.md index 92daa332..a6060a73 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,9 @@ +
+ # rustlings πŸ¦€β€οΈ +
+ 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)_ diff --git a/oranda.json b/oranda.json index 503653a4..08cc234d 100644 --- a/oranda.json +++ b/oranda.json @@ -1,6 +1,5 @@ { "homepage": "https://rustlings.cool", - "readme_path": "website.md", "repository": "https://github.com/rust-lang/rustlings", "analytics": { "plausible": { diff --git a/website.md b/website.md deleted file mode 100644 index 92bedc8c..00000000 --- a/website.md +++ /dev/null @@ -1,176 +0,0 @@ -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! - -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.5.0) -git clone -b 5.5.0 --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.5.0) -git clone -b 5.5.0 --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/`. 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](./CONTRIBUTING.md). - -Development-focused discussion about Rustlings happens in the [**rustlings** stream](https://rust-lang.zulipchat.com/#narrow/stream/334454-rustlings) -on the [Rust Project Zulip](https://rust-lang.zulipchat.com). Feel free to start a new thread there -if you have ideas or suggestions! - -## Contributors ✨ - -Thanks goes to the wonderful people listed in [AUTHORS.md](./AUTHORS.md) πŸŽ‰ From 2d544f18b53102a11bc80be4e986c7f52f5262de Mon Sep 17 00:00:00 2001 From: liv Date: Wed, 17 May 2023 21:04:32 +0200 Subject: [PATCH 50/58] fix: revert back to using relative paths --- src/project.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/project.rs b/src/project.rs index 7865d927..ebebe27d 100644 --- a/src/project.rs +++ b/src/project.rs @@ -1,9 +1,9 @@ use glob::glob; use serde::{Deserialize, Serialize}; +use std::env; use std::error::Error; use std::path::PathBuf; use std::process::Command; -use std::{env, fs}; /// Contains the structure of resulting rust-project.json file /// and functions to build the data required to create the file @@ -42,9 +42,8 @@ impl RustAnalyzerProject { fn path_to_json(&mut self, path: PathBuf) -> Result<(), Box> { if let Some(ext) = path.extension() { if ext == "rs" { - let abspath = fs::canonicalize(path)?; self.crates.push(Crate { - root_module: abspath.display().to_string(), + root_module: path.display().to_string(), edition: "2021".to_string(), deps: Vec::new(), // This allows rust_analyzer to work inside #[test] blocks From f2de12aa3443af2e989a045d9035294184d36eee Mon Sep 17 00:00:00 2001 From: liv Date: Wed, 17 May 2023 21:05:51 +0200 Subject: [PATCH 51/58] release: 5.5.1 --- CHANGELOG.md | 7 +++++++ Cargo.lock | 2 +- Cargo.toml | 2 +- README.md | 8 ++++---- flake.nix | 2 +- src/main.rs | 2 +- 6 files changed, 15 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d4d64406..a802faaf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ + +## 5.5.1 (2023-05-17) + +#### Fixed + +- Reverted `rust-project.json` path generation due to an upstream `rust-analyzer` fix. + ## 5.5.0 (2023-05-17) diff --git a/Cargo.lock b/Cargo.lock index 16f771c7..a09d98f7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -441,7 +441,7 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "rustlings" -version = "5.5.0" +version = "5.5.1" dependencies = [ "argh", "assert_cmd", diff --git a/Cargo.toml b/Cargo.toml index 498bbf9b..eca091f4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustlings" description = "Small exercises to get you used to reading and writing Rust code!" -version = "5.5.0" +version = "5.5.1" authors = [ "Liv ", "Carol (Nichols || Goulding) ", diff --git a/README.md b/README.md index a6060a73..12bd3925 100644 --- a/README.md +++ b/README.md @@ -40,8 +40,8 @@ This will install Rustlings and give you access to the `rustlings` command. Run 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.5.0) -git clone -b 5.5.0 --depth 1 https://github.com/rust-lang/rustlings +# find out the latest version at https://github.com/rust-lang/rustlings/releases/latest (on edit 5.5.1) +git clone -b 5.5.1 --depth 1 https://github.com/rust-lang/rustlings cd rustlings # if nix version > 2.3 nix develop @@ -78,8 +78,8 @@ If you get a permission denied message, you might have to exclude the directory 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.5.0) -git clone -b 5.5.0 --depth 1 https://github.com/rust-lang/rustlings +# find out the latest version at https://github.com/rust-lang/rustlings/releases/latest (on edit 5.5.1) +git clone -b 5.5.1 --depth 1 https://github.com/rust-lang/rustlings cd rustlings cargo install --force --path . ``` diff --git a/flake.nix b/flake.nix index c8749197..5dbca5c2 100644 --- a/flake.nix +++ b/flake.nix @@ -22,7 +22,7 @@ rustlings = pkgs.rustPlatform.buildRustPackage { name = "rustlings"; - version = "5.5.0"; + version = "5.5.1"; buildInputs = cargoBuildInputs; diff --git a/src/main.rs b/src/main.rs index feb673da..0a9af2ec 100644 --- a/src/main.rs +++ b/src/main.rs @@ -26,7 +26,7 @@ mod run; mod verify; // In sync with crate version -const VERSION: &str = "5.5.0"; +const VERSION: &str = "5.5.1"; #[derive(FromArgs, PartialEq, Debug)] /// Rustlings is a collection of small exercises to get you used to writing and reading Rust code From a7257a1d1ef59642f692e2638085ec00a6f2f391 Mon Sep 17 00:00:00 2001 From: b1ue64 <77976308+b1ue64@users.noreply.github.com> Date: Sat, 20 May 2023 16:38:33 -0400 Subject: [PATCH 52/58] feat(iterators5): remove outdated part of hint --- info.toml | 3 --- 1 file changed, 3 deletions(-) diff --git a/info.toml b/info.toml index ac04fc7d..2add5f0c 100644 --- a/info.toml +++ b/info.toml @@ -897,9 +897,6 @@ hint = """ The documentation for the std::iter::Iterator trait contains numerous methods that would be helpful here. -Return 0 from count_collection_iterator to make the code compile in order to -test count_iterator. - The collection variable in count_collection_iterator is a slice of HashMaps. It needs to be converted into an iterator in order to use the iterator methods. From 8e62346f8625965f1dac9603f3297e726670b3d3 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Sun, 21 May 2023 09:39:25 +0000 Subject: [PATCH 53/58] docs: update AUTHORS.md [skip ci] --- AUTHORS.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/AUTHORS.md b/AUTHORS.md index a27c60e9..e0631ce8 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -300,6 +300,9 @@ authors. lionel-rowe
lionel-rowe

πŸ–‹ Ben
Ben

πŸ–‹ + + b1ue64
b1ue64

πŸ–‹ + From 15ad02c984ef355a451189b2708b93112afc1840 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Sun, 21 May 2023 09:39:26 +0000 Subject: [PATCH 54/58] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 1b9678e0..7978d245 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -2118,6 +2118,15 @@ "contributions": [ "content" ] + }, + { + "login": "b1ue64", + "name": "b1ue64", + "avatar_url": "https://avatars.githubusercontent.com/u/77976308?v=4", + "profile": "https://github.com/b1ue64", + "contributions": [ + "content" + ] } ], "contributorsPerLine": 8, From e35a84fcb3f448aa3c455fab8c3a6a13fd47e606 Mon Sep 17 00:00:00 2001 From: liv Date: Mon, 22 May 2023 11:09:57 +0200 Subject: [PATCH 55/58] chore(oranda): don't generate changelog pages --- oranda.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/oranda.json b/oranda.json index 08cc234d..18ef8c68 100644 --- a/oranda.json +++ b/oranda.json @@ -6,5 +6,5 @@ "domain": "rustlings.cool" } }, - "changelog": true + "changelog": false } From 9604ab66218a83710e0da1152ec75b5574f051a8 Mon Sep 17 00:00:00 2001 From: lazywalker Date: Tue, 23 May 2023 15:00:55 +0800 Subject: [PATCH 56/58] fix(exercises): use snake_case variables --- exercises/iterators/iterators5.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/exercises/iterators/iterators5.rs b/exercises/iterators/iterators5.rs index dcf0742d..d0fcc8ca 100644 --- a/exercises/iterators/iterators5.rs +++ b/exercises/iterators/iterators5.rs @@ -79,11 +79,11 @@ mod tests { #[test] fn count_complete_equals_for() { let map = get_map(); - let progressStates = vec![Progress::Complete, Progress::Some, Progress::None]; - for progressState in progressStates { + let progress_states = vec![Progress::Complete, Progress::Some, Progress::None]; + for progress_state in progress_states { assert_eq!( - count_for(&map, progressState), - count_iterator(&map, progressState) + count_for(&map, progress_state), + count_iterator(&map, progress_state) ); } } @@ -111,13 +111,13 @@ mod tests { #[test] fn count_collection_equals_for() { - let progressStates = vec![Progress::Complete, Progress::Some, Progress::None]; + let progress_states = vec![Progress::Complete, Progress::Some, Progress::None]; let collection = get_vec_map(); - for progressState in progressStates { + for progress_state in progress_states { assert_eq!( - count_collection_for(&collection, progressState), - count_collection_iterator(&collection, progressState) + count_collection_for(&collection, progress_state), + count_collection_iterator(&collection, progress_state) ); } } From b9cb9311672babb938127385a102a645d86e4cac Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 23 May 2023 09:05:58 +0000 Subject: [PATCH 57/58] docs: update AUTHORS.md [skip ci] --- AUTHORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS.md b/AUTHORS.md index e0631ce8..50a477c0 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -302,6 +302,7 @@ authors. b1ue64
b1ue64

πŸ–‹ + lazywalker
lazywalker

πŸ–‹ From 33224370eb98da79a2a0b1d6a470cfa6edab83f2 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Tue, 23 May 2023 09:05:59 +0000 Subject: [PATCH 58/58] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 7978d245..14ec3a98 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -2127,6 +2127,15 @@ "contributions": [ "content" ] + }, + { + "login": "lazywalker", + "name": "lazywalker", + "avatar_url": "https://avatars.githubusercontent.com/u/53956?v=4", + "profile": "https://github.com/lazywalker", + "contributions": [ + "content" + ] } ], "contributorsPerLine": 8,