1
0
mirror of https://github.com/rust-lang/rustlings.git synced 2025-12-26 00:11:49 +02:00

Compare commits

...

137 Commits
5.4.1 ... 5.5.0

Author SHA1 Message Date
liv
4c638e365f Merge branch 'main' of github.com:rust-lang/rustlings 2023-05-17 16:30:31 +02:00
liv
f452fd7bb0 release: 5.5.0 2023-05-17 16:30:22 +02:00
liv
6d1f8c5111 Merge pull request #1520 from rust-lang/all-contributors/add-Ben2917
docs: add Ben2917 as a contributor for content
2023-05-17 16:14:54 +02:00
allcontributors[bot]
ab61a0d5c7 docs: update .all-contributorsrc [skip ci] 2023-05-17 14:14:44 +00:00
allcontributors[bot]
af52fce275 docs: update AUTHORS.md [skip ci] 2023-05-17 14:14:43 +00:00
liv
656140d9e6 Merge pull request #1478 from Ben2917/improved_tests_for_iterators5
fix: Added some extra tests to validate iterators5 solution
2023-05-17 16:14:29 +02:00
liv
9508e97914 feat: write absolute root module paths for lsp 2023-05-17 16:14:10 +02:00
liv
a6f99645c6 chore: rustfmt 2023-05-17 16:02:39 +02:00
liv
fd84c2d8f7 Merge pull request #1519 from rust-lang/all-contributors/add-lionel-rowe
docs: add lionel-rowe as a contributor for content
2023-05-17 15:57:26 +02:00
allcontributors[bot]
eeb439eaf9 docs: update .all-contributorsrc [skip ci] 2023-05-17 13:57:11 +00:00
allcontributors[bot]
58cbdd71b6 docs: update AUTHORS.md [skip ci] 2023-05-17 13:57:10 +00:00
liv
81cd97902a Merge pull request #1487 from lionel-rowe/patch-1
feat(options2): better test for layered_option
2023-05-17 15:56:55 +02:00
liv
ccf4a78f5d Merge pull request #1518 from rust-lang/all-contributors/add-deedy5
docs: add deedy5 as a contributor for content
2023-05-17 15:56:10 +02:00
allcontributors[bot]
6abff39549 docs: update .all-contributorsrc [skip ci] 2023-05-17 13:55:29 +00:00
allcontributors[bot]
94c6131c59 docs: update AUTHORS.md [skip ci] 2023-05-17 13:55:28 +00:00
liv
05fcc246ae Merge pull request #1490 from deedy5/main
modules2.rs: add more information to hint
2023-05-17 15:55:13 +02:00
liv
9bfb7055e2 Merge pull request #1517 from rust-lang/all-contributors/add-rb5014
docs: add rb5014 as a contributor for content
2023-05-17 15:54:49 +02:00
allcontributors[bot]
c5fe42089d docs: update .all-contributorsrc [skip ci] 2023-05-17 13:54:40 +00:00
allcontributors[bot]
70cf7698ac docs: update AUTHORS.md [skip ci] 2023-05-17 13:54:39 +00:00
liv
b07680108b Merge pull request #1504 from rb5014/success-hints-feature
feat(main, verify): Show hint(s) after exercise completion
2023-05-17 15:54:24 +02:00
liv
d45ec21b3c Merge pull request #1513 from rust-lang/all-contributors/add-nmay231
docs: add nmay231 as a contributor for content
2023-05-10 10:50:01 +02:00
allcontributors[bot]
0d252636be docs: update .all-contributorsrc [skip ci] 2023-05-10 08:49:45 +00:00
allcontributors[bot]
70da26f649 docs: update AUTHORS.md [skip ci] 2023-05-10 08:49:44 +00:00
liv
b882da1ad4 Merge pull request #1512 from nmay231/main
fix(options3): panic when not matching to avoid false positives
2023-05-10 10:49:36 +02:00
Noah May
3ecb47ff2c fix(options3): panic when not matching to avoid false positives
Closes #1503
2023-05-09 15:13:18 -05:00
Romain Bayle
c44e3025f9 option success_hints added to the struct Watchargs instead of Args 2023-05-02 22:46:41 +02:00
liv
9ffcab07bf Merge pull request #1506 from rust-lang/all-contributors/add-az0977776
docs: add az0977776 as a contributor for content
2023-05-02 11:15:57 +00:00
allcontributors[bot]
583925c085 docs: update .all-contributorsrc [skip ci] 2023-05-02 11:15:49 +00:00
allcontributors[bot]
e631f3c78b docs: update AUTHORS.md [skip ci] 2023-05-02 11:15:48 +00:00
liv
9a6e57eec9 Merge pull request #1471 from az0977776/patch-2
docs: update line numbers in move_semantics2
2023-05-02 11:15:33 +00:00
Aaron Wang
d3fea5f15a Merge branch 'main' into patch-2 2023-05-01 19:10:56 -04:00
Romain Bayle
5d3696a9e6 feat(cli): added success-hints option for the rustlings command
closes #1373
2023-05-01 03:04:06 +02:00
liv
b75d2aa3f4 Merge pull request #1499 from rust-lang/all-contributors/add-esotuvaka
docs: add esotuvaka as a contributor for content
2023-04-28 08:40:25 +00:00
allcontributors[bot]
eb4079c674 docs: update .all-contributorsrc [skip ci] 2023-04-28 08:40:18 +00:00
allcontributors[bot]
72d0c53b33 docs: update AUTHORS.md [skip ci] 2023-04-28 08:40:17 +00:00
liv
6ae0525f7a Merge pull request #1498 from esotuvaka/main
chore: clarified cow owned_no_mutation comments
2023-04-28 08:39:59 +00:00
PiqqiDesigns
c4627e7112 chore: clarified cow owned_no_mutation comments 2023-04-27 15:49:40 -07:00
liv
6d4a980b04 Merge pull request #1491 from rust-lang/all-contributors/add-akgerber
docs: add akgerber as a contributor for content
2023-04-22 13:48:59 +00:00
allcontributors[bot]
545a726252 docs: update .all-contributorsrc [skip ci] 2023-04-22 13:48:42 +00:00
allcontributors[bot]
065cd0170e docs: update AUTHORS.md [skip ci] 2023-04-22 13:48:41 +00:00
liv
a7eeaa3a4b Merge pull request #1484 from akgerber/move2_comment_fix
fix(move_semantics2): fix line number comment
2023-04-22 13:48:23 +00:00
deedy5
e2da663628 Update info.toml
modules2.rs: add more information to hint
2023-04-21 15:51:52 +00:00
lionel-rowe
836134202e 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<T>`s.

The updated test can _only_ be solved by stacking `Option<T>`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.
2023-04-21 06:05:25 +01:00
Alan Gerber
319a8253ba 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.
2023-04-20 12:15:31 -04:00
liv
fc81bb15fe Merge pull request #1482 from rust-lang/all-contributors/add-smlavine
docs: add smlavine as a contributor for code
2023-04-18 15:54:06 +00:00
allcontributors[bot]
6209e7004e docs: update .all-contributorsrc [skip ci] 2023-04-18 15:51:25 +00:00
allcontributors[bot]
4944488287 docs: update AUTHORS.md [skip ci] 2023-04-18 15:51:24 +00:00
liv
0dc9c33b01 Merge pull request #1480 from smlavine/main
feat: Add "!" command to `rustlings watch`
2023-04-18 15:51:06 +00:00
Sebastian LaVine
a4a5691a7b feat: Add "!" command to rustlings watch 2023-04-16 21:44:08 -04:00
Your Name
352267871c fix: Added some extra tests to validate iterators5 solution
closes: #1387
2023-04-15 17:34:52 +01:00
Aaron Wang
8ed2cf7ef5 Update move_semantics2.rs 2023-04-10 22:36:21 -04:00
Aaron Wang
c74e0bfd18 docs: update line numbers in move_semantics2 2023-04-07 01:56:20 -04:00
liv
9fc336c7f7 Merge pull request #1469 from rust-lang/all-contributors/add-stornquist
docs: add stornquist as a contributor for content
2023-04-05 13:11:24 +00:00
allcontributors[bot]
5de7124eee docs: update .all-contributorsrc [skip ci] 2023-04-05 13:11:15 +00:00
allcontributors[bot]
2f33826063 docs: update AUTHORS.md [skip ci] 2023-04-05 13:11:14 +00:00
liv
087e076ec0 Merge pull request #1384 from stornquist/patch-1
fix(move_semantics2): add expected output comment
2023-04-05 13:10:57 +00:00
liv
b39b819725 Merge pull request #1468 from rust-lang/all-contributors/add-alexwh
docs: add alexwh as a contributor for content
2023-04-05 13:10:02 +00:00
allcontributors[bot]
d544bfcd6d docs: update .all-contributorsrc [skip ci] 2023-04-05 13:09:51 +00:00
allcontributors[bot]
c7adaa7d14 docs: update AUTHORS.md [skip ci] 2023-04-05 13:09:50 +00:00
liv
f86fa1e909 Merge pull request #1385 from alexwh/patch-1
chore: update move_semantics4.rs' hint
2023-04-05 13:09:20 +00:00
liv
2285b89aea Merge pull request #1467 from rust-lang/all-contributors/add-ktheory
docs: add ktheory as a contributor for content
2023-04-05 13:07:58 +00:00
allcontributors[bot]
16ca871544 docs: update .all-contributorsrc [skip ci] 2023-04-05 13:06:59 +00:00
allcontributors[bot]
722c7910e4 docs: update AUTHORS.md [skip ci] 2023-04-05 13:06:58 +00:00
liv
ab6aa23cec Merge pull request #1391 from ktheory/ktheory/iter5
docs: clarify instructions on iterators5.rs
2023-04-05 13:06:43 +00:00
liv
5fd3dfe01b Merge pull request #1452 from guoard/markdown-linter
feat(docs): add markdown linter for exercises README.md files
2023-04-05 13:06:17 +00:00
liv
8a7f437641 Merge pull request #1466 from rust-lang/all-contributors/add-poneciak57
docs: add poneciak57 as a contributor for content
2023-04-05 13:05:38 +00:00
allcontributors[bot]
63a467af31 docs: update .all-contributorsrc [skip ci] 2023-04-05 13:05:30 +00:00
allcontributors[bot]
af365f444f docs: update AUTHORS.md [skip ci] 2023-04-05 13:05:29 +00:00
liv
9a9b487abd Merge pull request #1463 from poneciak57/feature/test4_panic
feat: add tests4.rs exercise
2023-04-05 13:05:14 +00:00
poneciak
102d7f3d0e changed comments in tests
also fixed small logical issue in `Rectangle::new()` where u could create rectangle with width or height equals 0
2023-04-05 13:24:14 +02:00
poneciak
c4974ac782 added required changes
- fixed grammar in hint and added more specific link
- added comments in test functions
- changed introduction paragraph
2023-04-05 13:09:13 +02:00
poneciak
27b7579566 created task 2023-04-05 08:18:51 +02:00
liv
01fa21f160 Merge pull request #1461 from rust-lang/all-contributors/add-sagarvora
docs: add sagarvora as a contributor for content
2023-04-02 10:46:50 +00:00
allcontributors[bot]
54d21dc7c1 docs: update .all-contributorsrc [skip ci] 2023-04-02 10:45:43 +00:00
allcontributors[bot]
2f2fd43771 docs: update AUTHORS.md [skip ci] 2023-04-02 10:45:42 +00:00
liv
2ca4ee2a54 Merge pull request #1460 from sagarvora/lifetimes-first
fix: move lifetimes above tests in recommended order
2023-04-02 10:45:28 +00:00
Sagar Vora
b1fb38e73c fix: move lifetimes above tests in recommended order 2023-04-02 12:25:24 +05:30
liv
09dc7058c9 Merge pull request #1456 from rust-lang/all-contributors/add-ahresse
docs: add ahresse as a contributor for content
2023-03-31 13:31:47 +00:00
allcontributors[bot]
75f0ab65d1 docs: update .all-contributorsrc [skip ci] 2023-03-31 13:31:33 +00:00
allcontributors[bot]
391e5d121a docs: update AUTHORS.md [skip ci] 2023-03-31 13:31:32 +00:00
liv
6f84887f60 Merge pull request #1454 from ahresse/ahresse/remove_trailing_spaces
fix: remove trailing spaces
2023-03-31 13:31:16 +00:00
liv
3e44060b5b Merge pull request #1455 from rust-lang/all-contributors/add-keogami
docs: add keogami as a contributor for doc
2023-03-31 13:29:40 +00:00
allcontributors[bot]
84dcd51d37 docs: update .all-contributorsrc [skip ci] 2023-03-31 13:29:30 +00:00
allcontributors[bot]
e185e27273 docs: update AUTHORS.md [skip ci] 2023-03-31 13:29:29 +00:00
liv
e2eb24761f Merge pull request #1453 from keogami/patch-1
Split quick installation commands into two separate blocks
2023-03-31 13:29:16 +00:00
Alexandre ESSE
d7111cb4a3 fix(main.rs): remove trailing spaces 2023-03-31 11:58:15 +02:00
Alexandre ESSE
22bb662d3e fix(exercises): remove trailing spaces 2023-03-31 11:58:15 +02:00
Keogami
8c4a7bea5f docs(README.md): split quick installation commands into two separate code blocks
Having the two quick installation commands in two separate code blocks makes it easy to copy them through the github's `copy to clipboard` button
2023-03-31 02:26:23 +05:30
Ali Afsharzadeh
382e16eb7e feat(docs): add markdown linter for exercises README.md files 2023-03-30 19:53:22 +03:30
liv
362c1b0d11 Merge pull request #1450 from guoard/patch-2
docs(error_handling): resolve markdownlint warnings
2023-03-30 09:19:20 +00:00
Ali Afsharzadeh
1db646474e docs(error_handling): resolve markdown linter warnings 2023-03-29 21:13:27 +03:30
liv
fbec311844 Merge pull request #1447 from rust-lang/all-contributors/add-guoard
docs: add guoard as a contributor for content
2023-03-28 10:27:00 +00:00
allcontributors[bot]
347462d87e docs: update .all-contributorsrc [skip ci] 2023-03-28 10:26:46 +00:00
allcontributors[bot]
99bd7181f9 docs: update AUTHORS.md [skip ci] 2023-03-28 10:26:45 +00:00
liv
92f09dbe81 Merge pull request #1445 from guoard/patch-1
docs(variables): wrap mut keyword with backtick
2023-03-28 10:26:32 +00:00
liv
4b1fe0a1cc Merge pull request #1446 from rust-lang/all-contributors/add-ryanwhitehouse
docs: add ryanwhitehouse as a contributor for content
2023-03-28 10:26:10 +00:00
allcontributors[bot]
78f4d66364 docs: update .all-contributorsrc [skip ci] 2023-03-28 10:25:47 +00:00
allcontributors[bot]
13356e16a3 docs: update AUTHORS.md [skip ci] 2023-03-28 10:25:46 +00:00
liv
e0e0b3f387 Merge pull request #1432 from ryanwhitehouse/main
docs:clarify instructions on hashmaps2.rs
2023-03-28 10:25:31 +00:00
Ali Afsharzadeh
592694036f docs(variables): wrap mut keyword with backtick 2023-03-28 09:58:59 +03:30
liv
b21a4ac12b Merge pull request #1443 from rust-lang/all-contributors/add-VegardMatthey
docs: add VegardMatthey as a contributor for content
2023-03-27 11:31:07 +00:00
allcontributors[bot]
5e43c7aba5 docs: update .all-contributorsrc [skip ci] 2023-03-27 11:30:57 +00:00
allcontributors[bot]
db993899d3 docs: update AUTHORS.md [skip ci] 2023-03-27 11:30:56 +00:00
liv
e2de7b8ae3 Merge pull request #1442 from VegardMatthey/main
docs: fixed a spelling mistake for the hint in exercise iterators2
2023-03-27 11:30:42 +00:00
Vegard Matthey
95e51f384e fixed a spelling mistake in info.toml 2023-03-26 23:25:59 +02:00
liv
4ff38c7bf3 Merge pull request #1441 from rust-lang/all-contributors/add-javihernant
docs: add javihernant as a contributor for content
2023-03-26 13:23:36 +00:00
allcontributors[bot]
faf4d9a888 docs: update .all-contributorsrc [skip ci] 2023-03-26 13:23:19 +00:00
allcontributors[bot]
18a9510048 docs: update AUTHORS.md [skip ci] 2023-03-26 13:23:18 +00:00
liv
2012641610 Merge pull request #1428 from javihernant/changeLtReadme
change order of references in README.md
2023-03-26 13:23:02 +00:00
liv
864e741dd8 reword hashmaps2 a bit more 2023-03-26 15:21:21 +02:00
liv
22eb7e3847 Merge pull request #1440 from rust-lang/all-contributors/add-navicore
docs: add navicore as a contributor for content
2023-03-26 12:50:45 +00:00
allcontributors[bot]
766b83b513 docs: update .all-contributorsrc [skip ci] 2023-03-26 12:50:14 +00:00
allcontributors[bot]
c28b78fae5 docs: update AUTHORS.md [skip ci] 2023-03-26 12:50:13 +00:00
liv
6d4a87227d Merge pull request #1437 from navicore/errors2-comment-error
correct comments in errors2.rs
2023-03-26 12:49:59 +00:00
liv
65b8770ce9 Merge pull request #1438 from tfpk/patch-2
feat(lifetimekata): Add info about Lifetimekata project
2023-03-26 12:49:26 +00:00
liv
2ef6fb66ac Merge pull request #1439 from rust-lang/all-contributors/add-eugkhp
docs: add eugkhp as a contributor for tool
2023-03-26 12:48:21 +00:00
allcontributors[bot]
82f72c3ec6 docs: update .all-contributorsrc [skip ci] 2023-03-26 12:48:10 +00:00
allcontributors[bot]
efd4d83731 docs: update AUTHORS.md [skip ci] 2023-03-26 12:48:09 +00:00
liv
8bab260587 Merge pull request #1435 from eugkhp/update-deps
cargo update to resolve #1430
2023-03-26 12:47:45 +00:00
Tom Kunc
d5449c992e feat(lifetimekata): Add info about Lifetimekata project 2023-03-25 20:00:28 +11:00
Ed Sweeney
4160b06c6c correct comments in errors2.rs 2023-03-24 21:52:58 -07:00
Eugene
6e9ed48f42 cargo update for to resolve #1430 2023-03-24 16:48:11 +01:00
Ryan Whitehouse
5687676014 docs:clarify instructions on hashmaps2.rs 2023-03-20 15:19:36 +01:00
hxztnxt
5d91c86cf2 change order of references in README.md 2023-03-16 00:56:15 +01:00
liv
9acefe8b3a Merge pull request #1425 from rust-lang/all-contributors/add-adamhb123
docs: add adamhb123 as a contributor for content
2023-03-14 11:15:30 +01:00
allcontributors[bot]
06fac0e570 docs: update .all-contributorsrc [skip ci] 2023-03-14 10:15:22 +00:00
allcontributors[bot]
e8b44a39e0 docs: update AUTHORS.md [skip ci] 2023-03-14 10:15:21 +00:00
liv
a55c8dc1a8 Merge pull request #1418 from adamhb123/vecs2.rs-naming-suggestion
Rename iteration var names in vec2.rs for clarity
2023-03-14 11:15:07 +01:00
Adam Brewer
7bab78c66d Rename iteration var names in vec2.rs for clarity
Resolves #1417
2023-03-10 14:13:06 -05:00
liv
5c5cd4c658 Merge pull request #1416 from rust-lang/all-contributors/add-Nagidal
docs: add Nagidal as a contributor for content
2023-03-10 18:03:30 +01:00
allcontributors[bot]
53a8318f32 docs: update .all-contributorsrc [skip ci] 2023-03-10 17:03:21 +00:00
allcontributors[bot]
31b208248b docs: update AUTHORS.md [skip ci] 2023-03-10 17:03:20 +00:00
liv
9c515c7863 Merge pull request #1415 from Nagidal/improve-hint-strings2
improve hint for strings2, #1407
2023-03-10 18:03:06 +01:00
Sven Siegmund
ec86b60e70 improve hint for strings2, #1407 2023-03-10 17:58:03 +01:00
Aaron Suggs
1ac66f372b 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!()`
2023-02-21 09:45:59 -05:00
Alex
89069f78b1 chore: update move_semantics4.rs' hint
after #144, the signature doesn't need changing anymore
2023-02-18 19:26:40 +00:00
Sebastian Törnquist
fef8314d3d fix(move_semantics2): add expected output comment
You can easily get this to compile with `vec0` being `[]` and `vec1` being `[22, 44, 66, 88]`
2023-02-18 18:43:34 +01:00
32 changed files with 737 additions and 227 deletions

View File

@@ -1902,6 +1902,222 @@
"contributions": [
"tool"
]
},
{
"login": "Nagidal",
"name": "Nagidal",
"avatar_url": "https://avatars.githubusercontent.com/u/7075397?v=4",
"profile": "https://github.com/Nagidal",
"contributions": [
"content"
]
},
{
"login": "adamhb123",
"name": "Adam Brewer",
"avatar_url": "https://avatars.githubusercontent.com/u/25161597?v=4",
"profile": "https://adabrew.com",
"contributions": [
"content"
]
},
{
"login": "eugkhp",
"name": "Eugene",
"avatar_url": "https://avatars.githubusercontent.com/u/25910599?v=4",
"profile": "https://github.com/eugkhp",
"contributions": [
"tool"
]
},
{
"login": "navicore",
"name": "Ed Sweeney",
"avatar_url": "https://avatars.githubusercontent.com/u/110999?v=4",
"profile": "https://social.linux.pizza/@navicore",
"contributions": [
"content"
]
},
{
"login": "javihernant",
"name": "javihernant",
"avatar_url": "https://avatars.githubusercontent.com/u/73640929?v=4",
"profile": "https://github.com/javihernant",
"contributions": [
"content"
]
},
{
"login": "VegardMatthey",
"name": "Vegard",
"avatar_url": "https://avatars.githubusercontent.com/u/59250656?v=4",
"profile": "https://github.com/VegardMatthey",
"contributions": [
"content"
]
},
{
"login": "ryanwhitehouse",
"name": "Ryan Whitehouse",
"avatar_url": "https://avatars.githubusercontent.com/u/13400784?v=4",
"profile": "https://github.com/ryanwhitehouse",
"contributions": [
"content"
]
},
{
"login": "guoard",
"name": "Ali Afsharzadeh",
"avatar_url": "https://avatars.githubusercontent.com/u/65511355?v=4",
"profile": "https://github.com/guoard",
"contributions": [
"content"
]
},
{
"login": "keogami",
"name": "Keogami",
"avatar_url": "https://avatars.githubusercontent.com/u/41939011?v=4",
"profile": "http://keogami.ml",
"contributions": [
"doc"
]
},
{
"login": "ahresse",
"name": "Alexandre Esse",
"avatar_url": "https://avatars.githubusercontent.com/u/28402488?v=4",
"profile": "https://github.com/ahresse",
"contributions": [
"content"
]
},
{
"login": "sagarvora",
"name": "Sagar Vora",
"avatar_url": "https://avatars.githubusercontent.com/u/16315650?v=4",
"profile": "https://resilient.tech",
"contributions": [
"content"
]
},
{
"login": "poneciak57",
"name": "Kacper Poneta",
"avatar_url": "https://avatars.githubusercontent.com/u/94321164?v=4",
"profile": "https://github.com/poneciak57",
"contributions": [
"content"
]
},
{
"login": "ktheory",
"name": "Aaron Suggs",
"avatar_url": "https://avatars.githubusercontent.com/u/975?v=4",
"profile": "https://ktheory.com/",
"contributions": [
"content"
]
},
{
"login": "alexwh",
"name": "Alex",
"avatar_url": "https://avatars.githubusercontent.com/u/1723612?v=4",
"profile": "https://github.com/alexwh",
"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"
]
},
{
"login": "smlavine",
"name": "Sebastian LaVine",
"avatar_url": "https://avatars.githubusercontent.com/u/33563640?v=4",
"profile": "http://smlavine.com",
"contributions": [
"code"
]
},
{
"login": "akgerber",
"name": "Alan Gerber",
"avatar_url": "https://avatars.githubusercontent.com/u/201313?v=4",
"profile": "http://www.alangerber.us",
"contributions": [
"content"
]
},
{
"login": "esotuvaka",
"name": "Eric",
"avatar_url": "https://avatars.githubusercontent.com/u/104941850?v=4",
"profile": "http://esotuvaka.github.io",
"contributions": [
"content"
]
},
{
"login": "az0977776",
"name": "Aaron Wang",
"avatar_url": "https://avatars.githubusercontent.com/u/9172038?v=4",
"profile": "https://github.com/az0977776",
"contributions": [
"content"
]
},
{
"login": "nmay231",
"name": "Noah",
"avatar_url": "https://avatars.githubusercontent.com/u/35386821?v=4",
"profile": "https://github.com/nmay231",
"contributions": [
"content"
]
},
{
"login": "rb5014",
"name": "rb5014",
"avatar_url": "https://avatars.githubusercontent.com/u/105397317?v=4",
"profile": "https://github.com/rb5014",
"contributions": [
"content"
]
},
{
"login": "deedy5",
"name": "deedy5",
"avatar_url": "https://avatars.githubusercontent.com/u/65482418?v=4",
"profile": "https://github.com/deedy5",
"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"
]
},
{
"login": "Ben2917",
"name": "Ben",
"avatar_url": "https://avatars.githubusercontent.com/u/10279994?v=4",
"profile": "https://github.com/Ben2917",
"contributions": [
"content"
]
}
],
"contributorsPerLine": 8,

18
.github/workflows/lint.yml vendored Normal file
View File

@@ -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"

2
.markdownlint.yml Normal file
View File

@@ -0,0 +1,2 @@
# MD013/line-length Line length, Expected: 80
MD013: false

View File

@@ -270,6 +270,36 @@ authors.
<td align="center" valign="top" width="12.5%"><a href="https://nidhalmessaoudi.herokuapp.com"><img src="https://avatars.githubusercontent.com/u/63377412?v=4?s=100" width="100px;" alt="Nidhal Messaoudi"/><br /><sub><b>Nidhal Messaoudi</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=nidhalmessaoudi" title="Code">💻</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/MahdiBM"><img src="https://avatars.githubusercontent.com/u/54685446?v=4?s=100" width="100px;" alt="Mahdi Bahrami"/><br /><sub><b>Mahdi Bahrami</b></sub></a><br /><a href="#tool-MahdiBM" title="Tools">🔧</a></td>
</tr>
<tr>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/Nagidal"><img src="https://avatars.githubusercontent.com/u/7075397?v=4?s=100" width="100px;" alt="Nagidal"/><br /><sub><b>Nagidal</b></sub></a><br /><a href="#content-Nagidal" title="Content">🖋</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://adabrew.com"><img src="https://avatars.githubusercontent.com/u/25161597?v=4?s=100" width="100px;" alt="Adam Brewer"/><br /><sub><b>Adam Brewer</b></sub></a><br /><a href="#content-adamhb123" title="Content">🖋</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/eugkhp"><img src="https://avatars.githubusercontent.com/u/25910599?v=4?s=100" width="100px;" alt="Eugene"/><br /><sub><b>Eugene</b></sub></a><br /><a href="#tool-eugkhp" title="Tools">🔧</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://social.linux.pizza/@navicore"><img src="https://avatars.githubusercontent.com/u/110999?v=4?s=100" width="100px;" alt="Ed Sweeney"/><br /><sub><b>Ed Sweeney</b></sub></a><br /><a href="#content-navicore" title="Content">🖋</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/javihernant"><img src="https://avatars.githubusercontent.com/u/73640929?v=4?s=100" width="100px;" alt="javihernant"/><br /><sub><b>javihernant</b></sub></a><br /><a href="#content-javihernant" title="Content">🖋</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/VegardMatthey"><img src="https://avatars.githubusercontent.com/u/59250656?v=4?s=100" width="100px;" alt="Vegard"/><br /><sub><b>Vegard</b></sub></a><br /><a href="#content-VegardMatthey" title="Content">🖋</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/ryanwhitehouse"><img src="https://avatars.githubusercontent.com/u/13400784?v=4?s=100" width="100px;" alt="Ryan Whitehouse"/><br /><sub><b>Ryan Whitehouse</b></sub></a><br /><a href="#content-ryanwhitehouse" title="Content">🖋</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/guoard"><img src="https://avatars.githubusercontent.com/u/65511355?v=4?s=100" width="100px;" alt="Ali Afsharzadeh"/><br /><sub><b>Ali Afsharzadeh</b></sub></a><br /><a href="#content-guoard" title="Content">🖋</a></td>
</tr>
<tr>
<td align="center" valign="top" width="12.5%"><a href="http://keogami.ml"><img src="https://avatars.githubusercontent.com/u/41939011?v=4?s=100" width="100px;" alt="Keogami"/><br /><sub><b>Keogami</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=keogami" title="Documentation">📖</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/ahresse"><img src="https://avatars.githubusercontent.com/u/28402488?v=4?s=100" width="100px;" alt="Alexandre Esse"/><br /><sub><b>Alexandre Esse</b></sub></a><br /><a href="#content-ahresse" title="Content">🖋</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://resilient.tech"><img src="https://avatars.githubusercontent.com/u/16315650?v=4?s=100" width="100px;" alt="Sagar Vora"/><br /><sub><b>Sagar Vora</b></sub></a><br /><a href="#content-sagarvora" title="Content">🖋</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/poneciak57"><img src="https://avatars.githubusercontent.com/u/94321164?v=4?s=100" width="100px;" alt="Kacper Poneta"/><br /><sub><b>Kacper Poneta</b></sub></a><br /><a href="#content-poneciak57" title="Content">🖋</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://ktheory.com/"><img src="https://avatars.githubusercontent.com/u/975?v=4?s=100" width="100px;" alt="Aaron Suggs"/><br /><sub><b>Aaron Suggs</b></sub></a><br /><a href="#content-ktheory" title="Content">🖋</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/alexwh"><img src="https://avatars.githubusercontent.com/u/1723612?v=4?s=100" width="100px;" alt="Alex"/><br /><sub><b>Alex</b></sub></a><br /><a href="#content-alexwh" title="Content">🖋</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/stornquist"><img src="https://avatars.githubusercontent.com/u/42915664?v=4?s=100" width="100px;" alt="Sebastian Törnquist"/><br /><sub><b>Sebastian Törnquist</b></sub></a><br /><a href="#content-stornquist" title="Content">🖋</a></td>
<td align="center" valign="top" width="12.5%"><a href="http://smlavine.com"><img src="https://avatars.githubusercontent.com/u/33563640?v=4?s=100" width="100px;" alt="Sebastian LaVine"/><br /><sub><b>Sebastian LaVine</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=smlavine" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="12.5%"><a href="http://www.alangerber.us"><img src="https://avatars.githubusercontent.com/u/201313?v=4?s=100" width="100px;" alt="Alan Gerber"/><br /><sub><b>Alan Gerber</b></sub></a><br /><a href="#content-akgerber" title="Content">🖋</a></td>
<td align="center" valign="top" width="12.5%"><a href="http://esotuvaka.github.io"><img src="https://avatars.githubusercontent.com/u/104941850?v=4?s=100" width="100px;" alt="Eric"/><br /><sub><b>Eric</b></sub></a><br /><a href="#content-esotuvaka" title="Content">🖋</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/az0977776"><img src="https://avatars.githubusercontent.com/u/9172038?v=4?s=100" width="100px;" alt="Aaron Wang"/><br /><sub><b>Aaron Wang</b></sub></a><br /><a href="#content-az0977776" title="Content">🖋</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/nmay231"><img src="https://avatars.githubusercontent.com/u/35386821?v=4?s=100" width="100px;" alt="Noah"/><br /><sub><b>Noah</b></sub></a><br /><a href="#content-nmay231" title="Content">🖋</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/rb5014"><img src="https://avatars.githubusercontent.com/u/105397317?v=4?s=100" width="100px;" alt="rb5014"/><br /><sub><b>rb5014</b></sub></a><br /><a href="#content-rb5014" title="Content">🖋</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/deedy5"><img src="https://avatars.githubusercontent.com/u/65482418?v=4?s=100" width="100px;" alt="deedy5"/><br /><sub><b>deedy5</b></sub></a><br /><a href="#content-deedy5" title="Content">🖋</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/lionel-rowe"><img src="https://avatars.githubusercontent.com/u/26078826?v=4?s=100" width="100px;" alt="lionel-rowe"/><br /><sub><b>lionel-rowe</b></sub></a><br /><a href="#content-lionel-rowe" title="Content">🖋</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/Ben2917"><img src="https://avatars.githubusercontent.com/u/10279994?v=4?s=100" width="100px;" alt="Ben"/><br /><sub><b>Ben</b></sub></a><br /><a href="#content-Ben2917" title="Content">🖋</a></td>
</tr>
</tbody>
</table>

View File

@@ -1,3 +1,38 @@
<a name="5.5.0"></a>
## 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
<a name="5.4.1"></a>
## 5.4.1 (2023-03-10)

280
Cargo.lock generated
View File

@@ -4,18 +4,18 @@ version = 3
[[package]]
name = "aho-corasick"
version = "0.7.18"
version = "0.7.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac"
dependencies = [
"memchr",
]
[[package]]
name = "argh"
version = "0.1.5"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e7317a549bc17c5278d9e72bb6e62c6aa801ac2567048e39ebc1c194249323e"
checksum = "ab257697eb9496bf75526f0217b5ed64636a9cfafa78b8365c71bd283fcef93e"
dependencies = [
"argh_derive",
"argh_shared",
@@ -23,22 +23,21 @@ dependencies = [
[[package]]
name = "argh_derive"
version = "0.1.5"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60949c42375351e9442e354434b0cba2ac402c1237edf673cac3a4bf983b8d3c"
checksum = "b382dbd3288e053331f03399e1db106c9fb0d8562ad62cb04859ae926f324fa6"
dependencies = [
"argh_shared",
"heck",
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
]
[[package]]
name = "argh_shared"
version = "0.1.5"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a61eb019cb8f415d162cb9f12130ee6bbe9168b7d953c17f4ad049e4051ca00"
checksum = "64cb94155d965e3d37ffbbe7cc5b82c3dd79dd33bd48e536f73d2cfb8d85506f"
[[package]]
name = "assert_cmd"
@@ -54,9 +53,9 @@ dependencies = [
[[package]]
name = "autocfg"
version = "1.0.1"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "bitflags"
@@ -78,17 +77,15 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "console"
version = "0.15.0"
version = "0.15.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a28b32d32ca44b70c3e4acd7db1babf555fa026e385fb95f18028f88848b3c31"
checksum = "c3d79fbe8970a77e3e34151cc13d3b3e248aa0faaecb9f6091fa07ebefe5ad60"
dependencies = [
"encode_unicode",
"lazy_static",
"libc",
"once_cell",
"regex",
"terminal_size",
"unicode-width",
"winapi 0.3.9",
"windows-sys 0.42.0",
]
[[package]]
@@ -117,14 +114,14 @@ dependencies = [
[[package]]
name = "filetime"
version = "0.2.15"
version = "0.2.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "975ccf83d8d9d0d84682850a38c8169027be83368805971cc4f238c2b245bc98"
checksum = "8a3de6e8d11b22ff9edc6d916f890800597d60f8b2da1caf2955c274638d6412"
dependencies = [
"cfg-if 1.0.0",
"libc",
"redox_syscall",
"winapi 0.3.9",
"windows-sys 0.45.0",
]
[[package]]
@@ -173,24 +170,15 @@ checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
[[package]]
name = "glob"
version = "0.3.0"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
[[package]]
name = "heck"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c"
dependencies = [
"unicode-segmentation",
]
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
[[package]]
name = "home"
version = "0.5.3"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2456aef2e6b6a9784192ae780c0f15bc57df0e918585282325e8c8ac27737654"
checksum = "747309b4b440c06d57b0b25f2aee03ee9b5e5397d288c60e21fc709bb98a7408"
dependencies = [
"winapi 0.3.9",
]
@@ -238,9 +226,9 @@ dependencies = [
[[package]]
name = "itoa"
version = "1.0.2"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d"
checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
[[package]]
name = "kernel32-sys"
@@ -266,24 +254,24 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]]
name = "libc"
version = "0.2.100"
version = "0.2.140"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1fa8cddc8fbbee11227ef194b5317ed014b8acbf15139bd716a18ad3fe99ec5"
checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c"
[[package]]
name = "log"
version = "0.4.14"
version = "0.4.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
dependencies = [
"cfg-if 1.0.0",
]
[[package]]
name = "memchr"
version = "2.4.1"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
name = "mio"
@@ -330,9 +318,9 @@ dependencies = [
[[package]]
name = "net2"
version = "0.2.37"
version = "0.2.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "391630d12b68002ae1e25e8f974306474966550ad82dac6886fb8910c19568ae"
checksum = "74d0df99cfcd2530b2e694f6e17e7f37b8e26bb23983ac530c0c97408837c631"
dependencies = [
"cfg-if 0.1.10",
"libc",
@@ -365,9 +353,9 @@ dependencies = [
[[package]]
name = "num-traits"
version = "0.2.14"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
dependencies = [
"autocfg",
]
@@ -378,12 +366,6 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
[[package]]
name = "once_cell"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9"
[[package]]
name = "predicates"
version = "1.0.8"
@@ -399,52 +381,52 @@ dependencies = [
[[package]]
name = "predicates-core"
version = "1.0.2"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57e35a3326b75e49aa85f5dc6ec15b41108cf5aee58eabb1f274dd18b73c2451"
checksum = "b794032607612e7abeb4db69adb4e33590fa6cf1149e95fd7cb00e634b92f174"
[[package]]
name = "predicates-tree"
version = "1.0.3"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7dd0fd014130206c9352efbdc92be592751b2b9274dff685348341082c6ea3d"
checksum = "368ba315fb8c5052ab692e68a0eefec6ec57b23a36959c14496f0b0df2c0cecf"
dependencies = [
"predicates-core",
"treeline",
"termtree",
]
[[package]]
name = "proc-macro2"
version = "1.0.28"
version = "1.0.53"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612"
checksum = "ba466839c78239c09faf015484e5cc04860f88242cff4d03eb038f04b4699b73"
dependencies = [
"unicode-xid",
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.9"
version = "1.0.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc"
dependencies = [
"proc-macro2",
]
[[package]]
name = "redox_syscall"
version = "0.2.10"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff"
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
dependencies = [
"bitflags",
]
[[package]]
name = "regex"
version = "1.5.5"
version = "1.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286"
checksum = "cce168fea28d3e05f158bda4576cf0c844d5045bc2cc3620fa0292ed5bb5814c"
dependencies = [
"aho-corasick",
"memchr",
@@ -453,13 +435,13 @@ dependencies = [
[[package]]
name = "regex-syntax"
version = "0.6.25"
version = "0.6.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
[[package]]
name = "rustlings"
version = "5.4.0"
version = "5.5.0"
dependencies = [
"argh",
"assert_cmd",
@@ -477,9 +459,9 @@ dependencies = [
[[package]]
name = "ryu"
version = "1.0.5"
version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041"
[[package]]
name = "same-file"
@@ -492,29 +474,29 @@ dependencies = [
[[package]]
name = "serde"
version = "1.0.129"
version = "1.0.158"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d1f72836d2aa753853178eda473a3b9d8e4eefdaf20523b919677e6de489f8f1"
checksum = "771d4d9c4163ee138805e12c710dd365e4f44be8be0503cb1bb9eb989425d9c9"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.129"
version = "1.0.158"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e57ae87ad533d9a56427558b516d0adac283614e347abf85b0dc0cbbf0a249f3"
checksum = "e801c1712f48475582b7696ac71e0ca34ebb30e09338425384269d9717c62cad"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 2.0.8",
]
[[package]]
name = "serde_json"
version = "1.0.81"
version = "1.0.94"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c"
checksum = "1c533a59c9d8a93a09c6ab31f0fd5e5f4dd1b8fc9434804029839884765d04ea"
dependencies = [
"itoa",
"ryu",
@@ -523,72 +505,69 @@ dependencies = [
[[package]]
name = "slab"
version = "0.4.4"
version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c307a32c1c5c437f38c7fd45d753050587732ba8628319fbdf12a7e289ccc590"
checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d"
dependencies = [
"autocfg",
]
[[package]]
name = "syn"
version = "1.0.75"
version = "1.0.109"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7f58f7e8eaa0009c5fec437aabf511bd9933e4b2d7407bd05273c01a8906ea7"
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
"unicode-ident",
]
[[package]]
name = "terminal_size"
version = "0.1.17"
name = "syn"
version = "2.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df"
checksum = "bcc02725fd69ab9f26eab07fad303e2497fad6fb9eba4f96c4d1687bdf704ad9"
dependencies = [
"libc",
"winapi 0.3.9",
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "termtree"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76"
[[package]]
name = "toml"
version = "0.5.9"
version = "0.5.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7"
checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234"
dependencies = [
"serde",
]
[[package]]
name = "treeline"
version = "0.1.0"
name = "unicode-ident"
version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7f741b240f1a48843f9b8e0444fb55fb2a4ff67293b50a9179dfd5ea67f8d41"
[[package]]
name = "unicode-segmentation"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b"
checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4"
[[package]]
name = "unicode-width"
version = "0.1.8"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
[[package]]
name = "unicode-xid"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
[[package]]
name = "walkdir"
version = "2.3.2"
version = "2.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56"
checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698"
dependencies = [
"same-file",
"winapi 0.3.9",
"winapi-util",
]
@@ -635,6 +614,87 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-sys"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows-sys"
version = "0.45.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
[[package]]
name = "windows_aarch64_msvc"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
[[package]]
name = "windows_i686_gnu"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
[[package]]
name = "windows_i686_msvc"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
[[package]]
name = "windows_x86_64_gnu"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
[[package]]
name = "windows_x86_64_msvc"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
[[package]]
name = "ws2_32-sys"
version = "0.2.1"

View File

@@ -1,6 +1,6 @@
[package]
name = "rustlings"
version = "5.4.1"
version = "5.5.0"
authors = [
"Liv <mokou@fastmail.com>",
"Carol (Nichols || Goulding) <carol.nichols@gmail.com>",

View File

@@ -22,7 +22,10 @@ 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:
```
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/
```
@@ -33,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
@@ -71,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 .
```

View File

@@ -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)
- [`FromStr` trait](https://doc.rust-lang.org/std/str/trait.FromStr.html)

View File

@@ -1,5 +1,6 @@
# Error handling
Most errors aren’t serious enough to require the program to stop entirely.
Most errors aren’t serious enough to require the program to stop entirely.
Sometimes, when a function fails, it’s for a reason that you can easily interpret and respond to.
For example, if you try to open a file and that operation fails because the file doesn’t exist, you might want to create the file instead of terminating the process.

View File

@@ -2,7 +2,7 @@
// Say we're writing a game where you can buy items with tokens. All items cost
// 5 tokens, and whenever you purchase items there is a processing fee of 1
// token. A player of the game will type in how many items they want to buy,
// and the `total_cost` function will calculate the total number of tokens.
// and the `total_cost` function will calculate the total cost of the tokens.
// Since the player typed in the quantity, though, we get it as a string-- and
// they might have typed anything, not just numbers!

View File

@@ -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

View File

@@ -1,11 +1,13 @@
// hashmaps2.rs
// A basket of fruits in the form of a hash map is given. The key
// represents the name of the fruit and the value represents how many
// of that particular fruit is in the basket. You have to put *MORE
// THAN 11* fruits in the basket. Three types of fruits - Apple (4),
// Mango (2) and Lychee (5) are already given in the basket. You are
// not allowed to insert any more of these fruits!
// We're collecting different fruits to bake a delicious fruit cake.
// For this, we have a basket, which we'll represent in the form of a hash
// map. The key represents the name of each fruit we collect and the value
// represents how many of that particular fruit we have collected.
// Three types of fruits - Apple (4), Mango (2) and Lychee (5) are already
// in the basket hash map.
// You must add fruit to the basket so that there is at least
// one of each kind and more than 11 in total - we have a lot of mouths to feed.
// You are not allowed to insert any more of these fruits!
//
// Make me pass the tests!
//
@@ -34,8 +36,8 @@ fn fruit_basket(basket: &mut HashMap<Fruit, u32>) {
];
for fruit in fruit_kinds {
// TODO: Put new fruits if not already present. Note that you
// are not allowed to put any type of fruit that's already
// TODO: Insert new fruits if they are not already present in the basket.
// Note that you are not allowed to put any type of fruit that's already
// present!
}
}
@@ -44,6 +46,7 @@ fn fruit_basket(basket: &mut HashMap<Fruit, u32>) {
mod tests {
use super::*;
// Don't modify this function!
fn get_fruit_basket() -> HashMap<Fruit, u32> {
let mut basket = HashMap::<Fruit, u32>::new();
basket.insert(Fruit::Apple, 4);

View File

@@ -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
@@ -67,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]
@@ -85,12 +98,28 @@ 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)
);
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));
}
#[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<String, Progress> {

View File

@@ -3,15 +3,20 @@
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
learning to write lifetime annotations.
## Further information
- [Validating References with Lifetimes](https://doc.rust-lang.org/book/ch10-03-lifetime-syntax.html)
- [Lifetimes (in Rust By Example)](https://doc.rust-lang.org/stable/rust-by-example/scope/lifetime.html)
- [Validating References with Lifetimes](https://doc.rust-lang.org/book/ch10-03-lifetime-syntax.html)

View File

@@ -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.

View File

@@ -1,12 +1,16 @@
// move_semantics2.rs
// 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() {
let vec0 = Vec::new();
// Do not move the following line!
let mut vec1 = fill_vec(vec0);
// Do not change the following line!

View File

@@ -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

View File

@@ -18,17 +18,22 @@ mod tests {
#[test]
fn layered_option() {
let mut range = 10;
let mut optional_integers: Vec<Option<i8>> = Vec::new();
for i in 0..(range + 1) {
let range = 10;
let mut optional_integers: Vec<Option<i8>> = 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<T>
// You can stack `Option<T>`'s into while let and if let
// You can stack `Option<T>`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);
}
}

View File

@@ -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.
}

View File

@@ -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.

View File

@@ -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) {

45
exercises/tests/tests4.rs Normal file
View File

@@ -0,0 +1,45 @@
// tests4.rs
// 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
struct Rectangle {
width: i32,
height: i32
}
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!")
}
Rectangle {width, height}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn correct_width_and_height() {
// 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 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 program panics when we try to create rectangle with negative height
let _rect = Rectangle::new(10, -10);
}
}

View File

@@ -30,7 +30,7 @@ fn main() {
if results.len() != 10 {
panic!("Oh no! All the spawned threads did not finish!");
}
println!();
for (i, result) in results.into_iter().enumerate() {
println!("thread {} took {}ms", i, result);

View File

@@ -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)

View File

@@ -2,7 +2,7 @@
In Rust, variables are immutable by default.
When a variable is immutable, once a value is bound to a name, you can’t change that value.
You can make them mutable by adding mut in front of the variable name.
You can make them mutable by adding `mut` in front of the variable name.
## Further information

View File

@@ -9,7 +9,7 @@
// I AM NOT DONE
fn vec_loop(mut v: Vec<i32>) -> Vec<i32> {
for i in v.iter_mut() {
for element in v.iter_mut() {
// TODO: Fill this up so that each element in the Vec `v` is
// multiplied by 2.
???
@@ -20,7 +20,7 @@ fn vec_loop(mut v: Vec<i32>) -> Vec<i32> {
}
fn vec_map(v: &Vec<i32>) -> Vec<i32> {
v.iter().map(|num| {
v.iter().map(|element| {
// TODO: Do the same thing as above - but instead of mutating the
// Vec, you can just return the new number!
???

View File

@@ -22,7 +22,7 @@
rustlings =
pkgs.rustPlatform.buildRustPackage {
name = "rustlings";
version = "5.4.1";
version = "5.5.0";
buildInputs = cargoBuildInputs;

View File

@@ -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`"""
@@ -439,7 +438,9 @@ mode = "compile"
hint = """
Yes, it would be really easy to fix this by just changing the value bound to `word` to be a
string slice instead of a `String`, wouldn't it?? There is a way to add one character to line
9, though, that will coerce the `String` into a string slice."""
9, though, that will coerce the `String` into a string slice.
Side note: If you're interested in learning about how this kind of reference conversion works, you can jump ahead in the book and read this part in the smart pointers chapter: https://doc.rust-lang.org/stable/book/ch15-02-deref.html#implicit-deref-coercions-with-functions-and-methods"""
[[exercises]]
name = "strings3"
@@ -477,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"
@@ -746,6 +748,33 @@ hint = """
To find the best solution to this challenge you're going to need to think back to your
knowledge of traits, specifically Trait Bound Syntax - you may also need this: `use std::fmt::Display;`."""
# LIFETIMES
[[exercises]]
name = "lifetimes1"
path = "exercises/lifetimes/lifetimes1.rs"
mode = "compile"
hint = """
Let the compiler guide you. Also take a look at the book if you need help:
https://doc.rust-lang.org/book/ch10-03-lifetime-syntax.html"""
[[exercises]]
name = "lifetimes2"
path = "exercises/lifetimes/lifetimes2.rs"
mode = "compile"
hint = """
Remember that the generic lifetime 'a will get the concrete lifetime that is equal to the smaller of the lifetimes of x and y.
You can take at least two paths to achieve the desired result while keeping the inner block:
1. Move the string2 declaration to make it live as long as string1 (how is result declared?)
2. Move println! into the inner block"""
[[exercises]]
name = "lifetimes3"
path = "exercises/lifetimes/lifetimes3.rs"
mode = "compile"
hint = """
If you use a lifetime annotation in a struct's fields, where else does it need to be added?"""
# TESTS
[[exercises]]
@@ -778,32 +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())`."""
# LIFETIMES
[[exercises]]
name = "lifetimes1"
path = "exercises/lifetimes/lifetimes1.rs"
mode = "compile"
name = "tests4"
path = "exercises/tests/tests4.rs"
mode = "test"
hint = """
Let the compiler guide you. Also take a look at the book if you need help:
https://doc.rust-lang.org/book/ch10-03-lifetime-syntax.html"""
We expect method `Rectangle::new()` to panic for negative values.
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"""
[[exercises]]
name = "lifetimes2"
path = "exercises/lifetimes/lifetimes2.rs"
mode = "compile"
hint = """
Remember that the generic lifetime 'a will get the concrete lifetime that is equal to the smaller of the lifetimes of x and y.
You can take at least two paths to achieve the desired result while keeping the inner block:
1. Move the string2 declaration to make it live as long as string1 (how is result declared?)
2. Move println! into the inner block"""
[[exercises]]
name = "lifetimes3"
path = "exercises/lifetimes/lifetimes3.rs"
mode = "compile"
hint = """
If you use a lifetime annotation in a struct's fields, where else does it need to be added?"""
# STANDARD LIBRARY TYPES
@@ -842,7 +855,7 @@ Create an iterator from the slice. Transform the iterated values by applying
the `capitalize_first` function. Remember to collect the iterator.
Step 3.
This is surprising similar to the previous solution. Collect is very powerful
This is surprisingly similar to the previous solution. Collect is very powerful
and very general. Rust just needs to know the desired type."""
[[exercises]]

View File

@@ -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
@@ -61,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")]
@@ -229,7 +233,7 @@ fn main() {
}
Subcommands::Verify(_subargs) => {
verify(&exercises, (0, exercises.len()), verbose)
verify(&exercises, (0, exercises.len()), verbose, false)
.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, _subargs.success_hints) {
Err(e) => {
println!(
"Error: Could not watch your progress. Error message was {:?}.",
@@ -298,13 +302,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!(" !<cmd> - 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}");
}
@@ -340,7 +352,11 @@ enum WatchStatus {
Unfinished,
}
fn watch(exercises: &[Exercise], verbose: bool) -> notify::Result<WatchStatus> {
fn watch(
exercises: &[Exercise],
verbose: bool,
success_hints: bool,
) -> notify::Result<WatchStatus> {
/* Clears the terminal with an ANSI escape code.
Works in UNIX and newer Windows terminals. */
fn clear_screen() {
@@ -356,7 +372,12 @@ fn watch(exercises: &[Exercise], verbose: bool) -> notify::Result<WatchStatus> {
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)))),
};
@@ -378,7 +399,12 @@ fn watch(exercises: &[Exercise], verbose: bool) -> notify::Result<WatchStatus> {
);
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();
@@ -433,8 +459,8 @@ started, here's a couple of notes about how Rustlings operates:
4. If an exercise doesn't make sense to you, feel free to open an issue on GitHub!
(https://github.com/rust-lang/rustlings/issues/new). We look at every issue,
and sometimes, other learners do too so you can help each other out!
5. If you want to use `rust-analyzer` with exercises, which provides features like
autocompletion, run the command `rustlings lsp`.
5. If you want to use `rust-analyzer` with exercises, which provides features like
autocompletion, run the command `rustlings lsp`.
Got all that? Great! To get started, run `rustlings watch` in order to get the first
exercise. Make sure to have your editor open!"#;

View File

@@ -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<dyn Error>> {
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<dyn Error>> {
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(())
}

View File

@@ -12,6 +12,7 @@ pub fn verify<'a>(
exercises: impl IntoIterator<Item = &'a Exercise>,
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<bool, ()> {
fn compile_only(exercise: &Exercise, success_hints: bool) -> Result<bool, ()> {
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<bool, ()> {
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<bool, ()> {
fn compile_and_run_interactively(exercise: &Exercise, success_hints: bool) -> Result<bool, ()> {
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<bool, ()> {
}
};
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<bool, ()> {
fn compile_and_test(exercise: &Exercise, run_mode: RunMode, verbose: bool, success_hints: bool) -> Result<bool, ()> {
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<String>) -> bool {
fn prompt_for_completion(exercise: &Exercise, prompt_output: Option<String>, 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<String>) ->
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<String>) ->
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!(