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

Compare commits

...

128 Commits
4.8.0 ... 5.0.0

Author SHA1 Message Date
mokou
5435b80841 chore: bump version 2022-07-16 14:30:04 +02:00
mokou
5138f22e00 doc: update book links 2022-07-16 14:25:10 +02:00
mokou
cc3e1a8511 doc: update changelog 2022-07-16 14:17:24 +02:00
mokou
c791cf4232 Merge branch '5.0-dev' 2022-07-15 14:31:49 +02:00
liv
f1c4caa37f Merge pull request #1059 from rust-lang/all-contributors/add-neilpate
docs: add neilpate as a contributor for content
2022-07-15 14:19:35 +02:00
allcontributors[bot]
e36c95bb3a docs: update .all-contributorsrc [skip ci] 2022-07-15 12:19:27 +00:00
allcontributors[bot]
bc25309763 docs: update AUTHORS.md [skip ci] 2022-07-15 12:19:26 +00:00
Neil Pate
c265b681b1 fix(quiz1): change function name 2022-07-15 14:18:31 +02:00
liv
52b9f199a2 Merge pull request #1058 from rust-lang/all-contributors/add-swhiteCQC
docs: add swhiteCQC as a contributor for content
2022-07-15 14:16:04 +02:00
allcontributors[bot]
211528c31b docs: update .all-contributorsrc [skip ci] 2022-07-15 12:15:57 +00:00
allcontributors[bot]
2b349e3b28 docs: update AUTHORS.md [skip ci] 2022-07-15 12:15:56 +00:00
mokou
1a7a3f5c8e fix(traits): update hint comments 2022-07-15 14:14:48 +02:00
Sam White
63b0c7e399 feat: add traits5.rs exercise 2022-07-15 14:14:15 +02:00
Sam White
599d634ee2 feat: Add traits4.rs exercise 2022-07-15 14:13:44 +02:00
Sam White
f43c6d7877 feat: Add traits3.rs exercise 2022-07-15 14:13:15 +02:00
Rod Elias
9b66b2a0e9 fix(try_from_into): fix function name 2022-07-15 14:08:51 +02:00
liv
64757698f4 Merge pull request #1057 from rust-lang/all-contributors/add-jayber
docs: add jayber as a contributor for content
2022-07-15 14:05:50 +02:00
allcontributors[bot]
2427184017 docs: update .all-contributorsrc [skip ci] 2022-07-15 12:05:36 +00:00
allcontributors[bot]
75ba60bda6 docs: update AUTHORS.md [skip ci] 2022-07-15 12:05:35 +00:00
jayber
1ef8dacaf6 feat: add lifetimes exercises 2022-07-15 14:03:38 +02:00
liv
7cabbab580 Merge pull request #1056 from rust-lang/all-contributors/add-Jzow
docs: add Jzow as a contributor for content
2022-07-15 13:49:25 +02:00
allcontributors[bot]
9329c51df0 docs: update .all-contributorsrc [skip ci] 2022-07-15 11:49:09 +00:00
allcontributors[bot]
bda4d548b4 docs: update AUTHORS.md [skip ci] 2022-07-15 11:49:08 +00:00
James Zow
1cc5df0e14 feat: add github actions config 2022-07-15 13:46:03 +02:00
liv
a0b3156347 Merge pull request #1055 from rust-lang/all-contributors/add-exdx
docs: add exdx as a contributor for content
2022-07-15 13:29:53 +02:00
allcontributors[bot]
c9332062ce docs: update .all-contributorsrc [skip ci] 2022-07-15 11:29:45 +00:00
allcontributors[bot]
b71429bef0 docs: update AUTHORS.md [skip ci] 2022-07-15 11:29:44 +00:00
exdx
a3b5278b42 feat: add threads3.rs exercise 2022-07-15 13:28:49 +02:00
mokou
a3c4c1ccb4 fix: re-add missing done comments 2022-07-15 13:24:11 +02:00
mokou
a6e86fc995 doc: update readme 2022-07-15 13:22:29 +02:00
mokou
0784f54141 doc: update contributing 2022-07-15 12:57:54 +02:00
mokou
b609f0431c feat: remove advanced_errs 2022-07-15 12:51:12 +02:00
mokou
4bebdb5f02 feat(as_ref_mut): add AsMut section 2022-07-15 12:50:01 +02:00
mokou
81d25aecff feat(try_from_into): add hint comments 2022-07-15 12:49:49 +02:00
mokou
74f44f55e3 feat(conversions): add hint comments 2022-07-15 12:34:10 +02:00
mokou
8cfedb1673 feat(clippy): add clippy3 2022-07-15 12:28:47 +02:00
mokou
7fc393bed4 chore: remove quiz4 2022-07-15 12:13:40 +02:00
mokou
d3a335bc64 feat(macros): add hint comments 2022-07-15 12:05:26 +02:00
liv
636c8ac03d Merge pull request #1054 from rust-lang/all-contributors/add-jaystile
docs: add jaystile as a contributor for content
2022-07-15 12:01:56 +02:00
allcontributors[bot]
b1f82890c9 docs: update .all-contributorsrc [skip ci] 2022-07-15 10:01:49 +00:00
allcontributors[bot]
7b371afc06 docs: update AUTHORS.md [skip ci] 2022-07-15 10:01:48 +00:00
mokou
f99eafc56f fix(threads): add hint comments 2022-07-15 11:59:53 +02:00
jaystile
b4f52cb937 feat: Adding threads1.rs with a focus on JoinHandles and waiting for
spawned threads to finish. Moved the original threads1.rs to threads2.rs
with the focus on the Mutex and modifying shared data. #892
2022-07-15 11:58:26 +02:00
liv
aa472f702e Merge pull request #1053 from rust-lang/all-contributors/add-pgjbz
docs: add pgjbz as a contributor for content
2022-07-14 18:30:20 +02:00
allcontributors[bot]
09ccadeec6 docs: update .all-contributorsrc [skip ci] 2022-07-14 16:29:51 +00:00
allcontributors[bot]
3e7e65b9f0 docs: update AUTHORS.md [skip ci] 2022-07-14 16:29:50 +00:00
mokou
20024d40c5 feat(iterators): update hint comments 2022-07-14 18:29:09 +02:00
Paulo Gabriel Justino Bezerra
251d0dda34 feat(iterators4): add factorial of zero test 2022-07-14 18:27:34 +02:00
Ryosuke YASUOKA
3c63ef0668 fix(iterators3): insert todo!() into divide() to compile without error 2022-07-14 18:19:35 +02:00
mokou
cf9629cb0e feat: move box/arc behind iterators 2022-07-14 18:17:23 +02:00
mokou
016d718a28 feat(tests): add hint comments 2022-07-14 18:15:47 +02:00
mokou
98b8d3f17d feat(traits): add hint comments 2022-07-14 18:14:41 +02:00
mokou
5979d408a9 feat: move generics3 to be quiz3 2022-07-14 18:11:18 +02:00
mokou
d61f79595a feat(generics): add hint comments 2022-07-14 18:11:05 +02:00
liv
69b07b2571 Merge pull request #1052 from rust-lang/all-contributors/add-nacairns1
docs: add nacairns1 as a contributor for content
2022-07-14 18:04:05 +02:00
allcontributors[bot]
537abe273a docs: update .all-contributorsrc [skip ci] 2022-07-14 16:03:58 +00:00
allcontributors[bot]
b2c82d9018 docs: update AUTHORS.md [skip ci] 2022-07-14 16:03:57 +00:00
liv
9f44550cdc Merge pull request #1051 from rust-lang/all-contributors/add-icecream17
docs: add icecream17 as a contributor for content
2022-07-14 18:03:24 +02:00
allcontributors[bot]
34c8833d06 docs: update .all-contributorsrc [skip ci] 2022-07-14 16:03:15 +00:00
allcontributors[bot]
5d02f6e516 docs: update AUTHORS.md [skip ci] 2022-07-14 16:03:14 +00:00
mokou
c34e2adcbb feat(errors): Improve comments and hints 2022-07-14 18:02:33 +02:00
Noah Cairns
5e1ca4b995 fix(errors5): improve exercise instructions 2022-07-14 17:59:29 +02:00
Steven nguyen
582320aded chore(errors1): use is_empty() instead of len() > 0
more idiomatic according to clippy
2022-07-14 17:55:07 +02:00
mokou
b71feed824 feat(options): add hint comments 2022-07-14 17:53:42 +02:00
mokou
06e4fd3765 feat(options1): rewrite to remove array stuff 2022-07-14 17:53:27 +02:00
mokou
b644558c19 fix: rename option to options 2022-07-14 17:34:50 +02:00
mokou
472d7944f9 fix(quiz2): add hint comment 2022-07-14 17:30:43 +02:00
mokou
c64b340622 feat: rework quiz2 2022-07-14 13:24:15 +02:00
mokou
f443f4e7b3 feat: move quiz2 to be strings4 2022-07-14 13:01:40 +02:00
mokou
ab8572e15b fix(hashmaps): adjust hint comments 2022-07-14 12:58:28 +02:00
Sateesh Basavaraju
1e54bc61e8 feat: Add hashmap3 exercise. 2022-07-14 12:57:47 +02:00
mokou
fe54d0f85b fix(modules): adjust hint comments 2022-07-14 12:35:49 +02:00
mokou
c1ed6b10fe feat(strings): add strings3 2022-07-14 12:31:28 +02:00
mokou
f5e4c16eed feat(strings): move before modules 2022-07-14 12:18:21 +02:00
liv
2f69f21f39 Merge pull request #1050 from rust-lang/all-contributors/add-YsuOS
docs: add YsuOS as a contributor for content
2022-07-14 12:12:40 +02:00
allcontributors[bot]
c92de1f8a6 docs: update .all-contributorsrc [skip ci] 2022-07-14 10:12:33 +00:00
allcontributors[bot]
0ddb997076 docs: update AUTHORS.md [skip ci] 2022-07-14 10:12:32 +00:00
mokou
c6bc97adc1 feat(enums3): add hint comment, remove enums1 hint 2022-07-14 12:11:38 +02:00
Ryosuke YASUOKA
d0e8efd19e feat(enums3): Add hint 2022-07-14 12:11:15 +02:00
liv
ed6d541d66 Merge pull request #1049 from rust-lang/all-contributors/add-camperdue42
docs: add camperdue42 as a contributor for content
2022-07-14 12:06:13 +02:00
allcontributors[bot]
62578269eb docs: update .all-contributorsrc [skip ci] 2022-07-14 10:06:04 +00:00
allcontributors[bot]
8fe02d33a9 docs: update AUTHORS.md [skip ci] 2022-07-14 10:06:03 +00:00
mokou
886d599c96 fix(structs): add hint comments 2022-07-14 12:04:54 +02:00
camperdue42
4531c21bf1 fix(structs3): Add panic! statement into structs3
closes #685
2022-07-14 12:04:30 +02:00
mokou
4dffa0d10d fix(structs1): rename to unit-like struct 2022-07-14 12:00:46 +02:00
mokou
19bec50399 feat(structs1): convert structs to use i32 types 2022-07-14 11:59:29 +02:00
mokou
2e62505143 feat(move_semantics): finish updating comments 2022-07-12 15:43:26 +02:00
exdx
16ff57bbff fix(move_semantics2): clarify referencing 2022-07-12 15:26:55 +02:00
mokou
bb0cf92b8b feat(move_semantics): clarify some hints 2022-07-12 15:25:31 +02:00
mokou
7452d0d603 fix(primitive_types): clean up 2022-07-12 15:22:01 +02:00
mokou
3c4c9c54c9 feat: remove collections to hashmaps 2022-07-12 15:18:05 +02:00
mokou
2f7fd51304 feat: move vec exercises into their own folder 2022-07-12 15:16:25 +02:00
mokou
8e1f617d34 feat(vec): update vec exercises 2022-07-12 15:05:47 +02:00
mokou
7af12ba9aa feat(primitive_types): fixups 2022-07-12 14:54:12 +02:00
mokou
6020ec1fe2 feat: reorder vec and primtypes before moving 2022-07-12 14:53:56 +02:00
Adam Sherwood
5812f1f27b fix(if2): Rename if2 exercise function to foo_if_fizz.
The reasoning here is pretty straightforward: you don't say "Hungry, if
eat." That doesn't make sense. We want to get "foo" back if given
"fizz", so it seems this makes far more sense as "Eat, if hungry," or in
this case, return `foo_if_fizz` is given.
2022-07-12 11:13:04 +02:00
mokou
4868d18ea3 feat(if): replace hints 2022-07-12 11:10:08 +02:00
mokou
742fb08e01 feat(functions): more small fixes 2022-07-12 11:08:29 +02:00
mokou
093a525450 fix(functions): clarify README wording 2022-07-11 14:00:12 +02:00
Cooper Gillan
b3ec8fe022 chore: Tweak punctuation in variables6.rs hint
While the meaning is still obvious as is, it makes a little more sense
to use a colon here =)
2022-07-11 13:53:31 +02:00
Cooper Gillan
9688609d08 chore: Update variables6.rs hint book link, wording
While the included link for variables6 does navigate to the correct
page, the header in the link itself does not actually exist so it
only loads the top of the page. There is, however, some text about
the difference between variables and constants in the "Constants"
section, so reword the hint some and update the link.
2022-07-11 13:53:09 +02:00
gavin
60410cfd2e fix(variables5): Add nudge for shadowing variable 2022-07-11 13:48:49 +02:00
mokou
81edc4234f fix(variables): reorder and redo hint texts 2022-07-11 13:43:41 +02:00
mokou
c3c21ad91f fix(intro): clarify hint usage 2022-07-11 13:35:16 +02:00
mokou
9ed4b0683e fix(intro1): link to exercise file in hint 2022-07-11 13:20:18 +02:00
mokou
0ded8a90c0 feat(intro1): add more hints 2022-07-11 13:19:19 +02:00
mokou
0aee54a82b chore: unify hint language use 2022-07-11 13:12:47 +02:00
mokou
ed0f278a8f chore: remove mod.rs files and exercises feature 2022-07-11 12:53:49 +02:00
liv
bf69145bb9 Merge pull request #1048 from rust-lang/all-contributors/add-Drew-Morris
docs: add Drew-Morris as a contributor for code
2022-07-11 11:59:41 +02:00
allcontributors[bot]
1caa388e92 docs: update .all-contributorsrc [skip ci] 2022-07-11 09:59:33 +00:00
allcontributors[bot]
11618b65c0 docs: update AUTHORS.md [skip ci] 2022-07-11 09:59:32 +00:00
liv
a475e09cfc Merge pull request #1044 from Drew-Morris/main
chore: Update spacing in Cargo.toml
2022-07-11 11:59:13 +02:00
liv
fba79ea793 Merge pull request #1047 from rust-lang/all-contributors/add-KatanaFluorescent
docs: add KatanaFluorescent as a contributor for code
2022-07-11 11:58:41 +02:00
allcontributors[bot]
440138af84 docs: update .all-contributorsrc [skip ci] 2022-07-11 09:58:19 +00:00
allcontributors[bot]
8835034bd2 docs: update AUTHORS.md [skip ci] 2022-07-11 09:58:18 +00:00
liv
5fbf28dfec Merge pull request #1038 from KatanaFluorescent/main
change edition to 2021 in exercices.rs
2022-07-11 11:57:59 +02:00
liv
2a12df4591 Merge pull request #1046 from rust-lang/all-contributors/add-0pling
docs: add 0pling as a contributor for content
2022-07-11 11:54:56 +02:00
allcontributors[bot]
995ba213e2 docs: update .all-contributorsrc [skip ci] 2022-07-11 09:53:39 +00:00
allcontributors[bot]
f73aec1a63 docs: update AUTHORS.md [skip ci] 2022-07-11 09:53:38 +00:00
liv
08e3cf494b Merge pull request #1034 from 0pling/main
docs: Add missing exercise to book chapter mapping
2022-07-11 11:53:20 +02:00
liv
36c43cb839 Merge pull request #1045 from rust-lang/all-contributors/add-klkl0808
docs: add klkl0808 as a contributor for content
2022-07-11 11:52:12 +02:00
allcontributors[bot]
c9e0d53ed2 docs: update .all-contributorsrc [skip ci] 2022-07-11 09:51:31 +00:00
allcontributors[bot]
c38d75481e docs: update AUTHORS.md [skip ci] 2022-07-11 09:51:30 +00:00
liv
612ae8b8f7 Merge pull request #1024 from klkl0808/patch-2
Update link to book in variables5
2022-07-11 11:51:13 +02:00
Drew Morris
df68d1a86e chore: Update spacing in Cargo.toml 2022-07-09 16:50:57 -06:00
KatanaFluorescent
a500ed2c3c change edition to 2021 in exercices.rs
workaround for this issue https://github.com/rust-lang/rustlings/issues/1022
2022-07-01 16:49:36 +02:00
0pling
be3944072c docs: Add missing exercise to book chapter mapping 2022-06-26 10:27:18 +08:00
Konstantin
baca5d62ae fix: update link to book 2022-06-13 21:30:25 +02:00
140 changed files with 1546 additions and 1093 deletions

View File

@@ -1236,6 +1236,141 @@
"contributions": [
"code"
]
},
{
"login": "klkl0808",
"name": "Konstantin",
"avatar_url": "https://avatars.githubusercontent.com/u/24694249?v=4",
"profile": "https://github.com/klkl0808",
"contributions": [
"content"
]
},
{
"login": "0pling",
"name": "0pling",
"avatar_url": "https://avatars.githubusercontent.com/u/104090344?v=4",
"profile": "https://github.com/0pling",
"contributions": [
"content"
]
},
{
"login": "KatanaFluorescent",
"name": "KatanaFluorescent",
"avatar_url": "https://avatars.githubusercontent.com/u/60199077?v=4",
"profile": "https://github.com/KatanaFluorescent",
"contributions": [
"code"
]
},
{
"login": "Drew-Morris",
"name": "Drew Morris",
"avatar_url": "https://avatars.githubusercontent.com/u/95818166?v=4",
"profile": "https://github.com/Drew-Morris",
"contributions": [
"code"
]
},
{
"login": "camperdue42",
"name": "camperdue42",
"avatar_url": "https://avatars.githubusercontent.com/u/43047763?v=4",
"profile": "https://github.com/camperdue42",
"contributions": [
"content"
]
},
{
"login": "YsuOS",
"name": "YsuOS",
"avatar_url": "https://avatars.githubusercontent.com/u/30138661?v=4",
"profile": "https://github.com/YsuOS",
"contributions": [
"content"
]
},
{
"login": "icecream17",
"name": "Steven Nguyen",
"avatar_url": "https://avatars.githubusercontent.com/u/58114641?v=4",
"profile": "https://lichess.org/@/StevenEmily",
"contributions": [
"content"
]
},
{
"login": "nacairns1",
"name": "nacairns1",
"avatar_url": "https://avatars.githubusercontent.com/u/94420090?v=4",
"profile": "https://noahcairns.dev",
"contributions": [
"content"
]
},
{
"login": "pgjbz",
"name": "Paulo Gabriel Justino Bezerra",
"avatar_url": "https://avatars.githubusercontent.com/u/22059237?v=4",
"profile": "https://github.com/pgjbz",
"contributions": [
"content"
]
},
{
"login": "jaystile",
"name": "Jason",
"avatar_url": "https://avatars.githubusercontent.com/u/46078028?v=4",
"profile": "https://github.com/jaystile",
"contributions": [
"content"
]
},
{
"login": "exdx",
"name": "exdx",
"avatar_url": "https://avatars.githubusercontent.com/u/31546601?v=4",
"profile": "https://exdx.github.io",
"contributions": [
"content"
]
},
{
"login": "Jzow",
"name": "James Zow",
"avatar_url": "https://avatars.githubusercontent.com/u/68860495?v=4",
"profile": "https://github.com/Jzow",
"contributions": [
"content"
]
},
{
"login": "jayber",
"name": "James Bromley",
"avatar_url": "https://avatars.githubusercontent.com/u/2474334?v=4",
"profile": "https://jamesabromley.wordpress.com/",
"contributions": [
"content"
]
},
{
"login": "swhiteCQC",
"name": "swhiteCQC",
"avatar_url": "https://avatars.githubusercontent.com/u/77438466?v=4",
"profile": "https://github.com/swhiteCQC",
"contributions": [
"content"
]
},
{
"login": "neilpate",
"name": "Neil Pate",
"avatar_url": "https://avatars.githubusercontent.com/u/7802334?v=4",
"profile": "https://github.com/neilpate",
"contributions": [
"content"
]
}
],
"contributorsPerLine": 8,

20
.github/workflows/rust.yml vendored Normal file
View File

@@ -0,0 +1,20 @@
name: Rustlings Tests
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
env:
CARGO_TERM_COLOR: always
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build
run: cargo build --verbose
- name: Run tests
run: cargo test --verbose

1
.gitignore vendored
View File

@@ -9,3 +9,4 @@ rust-project.json
.idea
.vscode
*.iml
*.o

View File

@@ -176,6 +176,25 @@ authors.
<td align="center"><a href="http://linkedin.com/in/lucasgrvarela"><img src="https://avatars.githubusercontent.com/u/37870368?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Lucas Grigolon Varela</b></sub></a><br /><a href="#content-lucasgrvarela" title="Content">🖋</a></td>
<td align="center"><a href="https://github.com/bufo24"><img src="https://avatars.githubusercontent.com/u/32884105?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Bufo</b></sub></a><br /><a href="#content-bufo24" title="Content">🖋</a></td>
<td align="center"><a href="http://rustnote.com"><img src="https://avatars.githubusercontent.com/u/77730378?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jack Clayton</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=jackos" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/klkl0808"><img src="https://avatars.githubusercontent.com/u/24694249?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Konstantin</b></sub></a><br /><a href="#content-klkl0808" title="Content">🖋</a></td>
<td align="center"><a href="https://github.com/0pling"><img src="https://avatars.githubusercontent.com/u/104090344?v=4?s=100" width="100px;" alt=""/><br /><sub><b>0pling</b></sub></a><br /><a href="#content-0pling" title="Content">🖋</a></td>
</tr>
<tr>
<td align="center"><a href="https://github.com/KatanaFluorescent"><img src="https://avatars.githubusercontent.com/u/60199077?v=4?s=100" width="100px;" alt=""/><br /><sub><b>KatanaFluorescent</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=KatanaFluorescent" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/Drew-Morris"><img src="https://avatars.githubusercontent.com/u/95818166?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Drew Morris</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=Drew-Morris" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/camperdue42"><img src="https://avatars.githubusercontent.com/u/43047763?v=4?s=100" width="100px;" alt=""/><br /><sub><b>camperdue42</b></sub></a><br /><a href="#content-camperdue42" title="Content">🖋</a></td>
<td align="center"><a href="https://github.com/YsuOS"><img src="https://avatars.githubusercontent.com/u/30138661?v=4?s=100" width="100px;" alt=""/><br /><sub><b>YsuOS</b></sub></a><br /><a href="#content-YsuOS" title="Content">🖋</a></td>
<td align="center"><a href="https://lichess.org/@/StevenEmily"><img src="https://avatars.githubusercontent.com/u/58114641?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Steven Nguyen</b></sub></a><br /><a href="#content-icecream17" title="Content">🖋</a></td>
<td align="center"><a href="https://noahcairns.dev"><img src="https://avatars.githubusercontent.com/u/94420090?v=4?s=100" width="100px;" alt=""/><br /><sub><b>nacairns1</b></sub></a><br /><a href="#content-nacairns1" title="Content">🖋</a></td>
<td align="center"><a href="https://github.com/pgjbz"><img src="https://avatars.githubusercontent.com/u/22059237?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Paulo Gabriel Justino Bezerra</b></sub></a><br /><a href="#content-pgjbz" title="Content">🖋</a></td>
<td align="center"><a href="https://github.com/jaystile"><img src="https://avatars.githubusercontent.com/u/46078028?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jason</b></sub></a><br /><a href="#content-jaystile" title="Content">🖋</a></td>
</tr>
<tr>
<td align="center"><a href="https://exdx.github.io"><img src="https://avatars.githubusercontent.com/u/31546601?v=4?s=100" width="100px;" alt=""/><br /><sub><b>exdx</b></sub></a><br /><a href="#content-exdx" title="Content">🖋</a></td>
<td align="center"><a href="https://github.com/Jzow"><img src="https://avatars.githubusercontent.com/u/68860495?v=4?s=100" width="100px;" alt=""/><br /><sub><b>James Zow</b></sub></a><br /><a href="#content-Jzow" title="Content">🖋</a></td>
<td align="center"><a href="https://jamesabromley.wordpress.com/"><img src="https://avatars.githubusercontent.com/u/2474334?v=4?s=100" width="100px;" alt=""/><br /><sub><b>James Bromley</b></sub></a><br /><a href="#content-jayber" title="Content">🖋</a></td>
<td align="center"><a href="https://github.com/swhiteCQC"><img src="https://avatars.githubusercontent.com/u/77438466?v=4?s=100" width="100px;" alt=""/><br /><sub><b>swhiteCQC</b></sub></a><br /><a href="#content-swhiteCQC" title="Content">🖋</a></td>
<td align="center"><a href="https://github.com/neilpate"><img src="https://avatars.githubusercontent.com/u/7802334?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Neil Pate</b></sub></a><br /><a href="#content-neilpate" title="Content">🖋</a></td>
</tr>
</table>

View File

@@ -1,3 +1,76 @@
<a name="5.0.0"></a>
## 5.0.0 (2022-07-16)
#### Features
- Hint comments in exercises now also include a reference to the
`hint` watch mode subcommand.
- **intro1**: Added more hints to point the user to the source file.
- **variables**: Switched variables3 and variables4.
- Moved `vec` and `primitive_types` exercises before `move_semantics`.
- Renamed `vec` to `vecs` to be more in line with the naming in general.
- Split up the `collections` exercises in their own folders.
- **vec2**: Added a second part of the function that provides an alternative,
immutable way of modifying vec values.
- **enums3**: Added a hint.
- Moved `strings` before `modules`.
- Added a `strings3` exercise to teach modifying strings.
- Added a `hashmaps3` exercise for some advanced usage of hashmaps.
- Moved the original `quiz2` to be `strings4`, since it only tested strings
anyways.
- Reworked `quiz2` into a new exercise that tests more chapters.
- Renamed `option` to `options`.
- **options1**: Rewrote parts of the exercise to remove the weird array
iteration stuff.
- Moved `generics3` to be `quiz3`.
- Moved box/arc exercises behind `iterators`.
- **iterators4**: Added a test for factorials of zero.
- Split `threads1` between two exercises, the first one focusing more on
`JoinHandle`s.
- Added a `threads3` exercises that uses `std::sync::mpsc`.
- Added a `clippy3` exercises with some more interesting checks.
- **as_ref_mut**: Added a section that actually tests `AsMut`.
- Added 3 new lifetimes exercises.
- Added 3 new traits exercises.
#### Bug Fixes
- **variables2**: Made output messages more verbose.
- **variables5**: Added a nudging hint about shadowing.
- **variables6**: Fixed link to book.
- **functions**: Clarified the README wording. Generally cleaned up
some hints and added some extra comments.
- **if2**: Renamed function name to `foo_if_fizz`.
- **move_semantics**: Clarified some hints.
- **quiz1**: Renamed the function name to be more verbose.
- **structs1**: Use an integer type instead of strings. Renamed "unit structs"
to "unit-like structs", as is used in the book.
- **structs3**: Added the `panic!` statement in from the beginning.
- **errors1**: Use `is_empty()` instead of `len() > 0`
- **errors3**: Improved the hint.
- **errors5**: Improved exercise instructions and the hint.
- **errors6**: Provided the skeleton of one of the functions that's supposed
to be implemented.
- **iterators3**: Inserted `todo!` into `divide()` to keep a compiler error
from happening.
- **from_str**: Added a hint comment about string error message conversion with
`Box<dyn Error>`.
- **try_from_into**: Fixed the function name in comment.
#### Removed
- Removed the legacy LSP feature that was using `mod.rs` files.
- Removed `quiz4`.
- Removed `advanced_errs`. These were the last exercises in the recommended
order, and I've always felt like they didn't quite fit in with the mostly
simple, book-following style we've had in Rustlings.
#### Housekeeping
- Added missing exercises to the book index.
- Updated spacing in Cargo.toml.
- Added a GitHub actions config so that tests run on every PR/commit.
<a name="4.8.0"></a>
## 4.8.0 (2022-07-01)

View File

@@ -21,7 +21,7 @@ _implement a new feature! ➡️ [open an Issue to discuss it first, then a Pull
`rustlings` is basically a glorified `rustc` wrapper. Therefore the source code
isn't really that complicated since the bulk of the work is done by `rustc`.
`src/main.rs` contains a simple `clap` CLI that loads from `src/verify.rs` and `src/run.rs`.
`src/main.rs` contains a simple `argh` CLI that connects to most of the other source files.
<a name="addex"></a>
### Adding an exercise
@@ -29,7 +29,7 @@ isn't really that complicated since the bulk of the work is done by `rustc`.
The first step is to add the exercise! Name the file `exercises/yourTopic/yourTopicN.rs`, make sure to
put in some helpful links, and link to sections of the book in `exercises/yourTopic/README.md`.
Next make sure it runs with `rustlings`. The exercise metadata is stored in `info.toml`, under the `exercises` array. The order of the `exercises` array determines the order the exercises are run by `rustlings verify`.
Next make sure it runs with `rustlings`. The exercise metadata is stored in `info.toml`, under the `exercises` array. The order of the `exercises` array determines the order the exercises are run by `rustlings verify` and `rustlings watch`.
Add the metadata for your exercise in the correct order in the `exercises` array. If you are unsure of the correct ordering, add it at the bottom and ask in your pull request. The exercise metadata should contain the following:
```diff
@@ -43,7 +43,7 @@ Add the metadata for your exercise in the correct order in the `exercises` array
...
```
The `mode` attribute decides whether Rustlings will only compile your exercise, or compile and test it. If you have tests to verify in your exercise, choose `test`, otherwise `compile`.
The `mode` attribute decides whether Rustlings will only compile your exercise, or compile and test it. If you have tests to verify in your exercise, choose `test`, otherwise `compile`. If you're working on a Clippy exercise, use `mode = "clippy"`.
That's all! Feel free to put up a pull request.
@@ -67,19 +67,19 @@ changes. There's a couple of things to watch out for:
#### Write correct commit messages
We follow the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0-beta.4/)
specification, because it makes it easier to generate changelogs automatically.
specification.
This means that you have to format your commit messages in a specific way. Say
you're working on adding a new exercise called `foobar1.rs`. You could write
the following commit message:
```
feat: Add foobar1.rs exercise
feat: add foobar1.rs exercise
```
If you're just fixing a bug, please use the `fix` type:
```
fix(verify): Make sure verify doesn't self-destruct
fix(verify): make sure verify doesn't self-destruct
```
The scope within the brackets is optional, but should be any of these:
@@ -96,7 +96,7 @@ When the commit also happens to close an existing issue, link it in the message
body:
```
fix: Update foobar
fix: update foobar
closes #101029908
```
@@ -104,13 +104,13 @@ closes #101029908
If you're doing simple changes, like updating a book link, use `chore`:
```
chore: Update exercise1.rs book link
chore: update exercise1.rs book link
```
If you're updating documentation, use `docs`:
```
docs: Add more information to Readme
docs: add more information to Readme
```
If, and only if, you're absolutely sure you want to make a breaking change
@@ -118,7 +118,7 @@ If, and only if, you're absolutely sure you want to make a breaking change
explain the breaking change in the message body:
```
fix!: Completely change verification
fix!: completely change verification
BREAKING CHANGE: This has to be done because lorem ipsum dolor
```
@@ -126,6 +126,5 @@ BREAKING CHANGE: This has to be done because lorem ipsum dolor
#### Pull Request Workflow
Once you open a Pull Request, it may be reviewed or labeled (or both) until
the maintainers accept your change. Then, [bors](https://github.com/bors) will
run the test suite with your changes and if it's successful, automatically
merge it in!
the maintainers accept your change. Please be patient, it may take some time
for this to happen!

2
Cargo.lock generated
View File

@@ -459,7 +459,7 @@ checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
[[package]]
name = "rustlings"
version = "4.7.1"
version = "4.8.0"
dependencies = [
"argh",
"assert_cmd",

View File

@@ -1,7 +1,7 @@
[package]
name = "rustlings"
version = "4.8.0"
authors = ["mokou <mokou@fastmail.com>", "Carol (Nichols || Goulding) <carol.nichols@gmail.com>"]
version = "5.0.0"
authors = ["Liv <mokou@fastmail.com>", "Carol (Nichols || Goulding) <carol.nichols@gmail.com>"]
edition = "2021"
[dependencies]
@@ -11,7 +11,7 @@ console = "0.15"
notify = "4.0"
toml = "0.5"
regex = "1.5"
serde= { version = "1.0", features = ["derive"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0.81"
home = "0.5.3"
glob = "0.3.0"
@@ -24,6 +24,3 @@ path = "src/main.rs"
assert_cmd = "0.11.0"
predicates = "1.0.1"
glob = "0.3.0"
[features]
exercises = []

View File

@@ -44,9 +44,9 @@ Start-BitsTransfer -Source https://raw.githubusercontent.com/rust-lang/rustlings
To install Rustlings. Same as on MacOS/Linux, you will have access to the `rustlings` command after it.
When you get a permission denied message then you have to exclude the directory where you placed the rustlings in your virus-scanner
If you get a permission denied message, you might have to exclude the directory where you cloned Rustlings in your antivirus.
## Browser:
## Browser
[Run on Repl.it](https://repl.it/github/rust-lang/rustlings)
@@ -57,8 +57,8 @@ When you get a permission denied message then you have to exclude the directory
Basically: Clone the repository at the latest tag, run `cargo install`.
```bash
# find out the latest version at https://github.com/rust-lang/rustlings/releases/latest (on edit 4.7.1)
git clone -b 4.7.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.0.0)
git clone -b 5.0.0 --depth 1 https://github.com/rust-lang/rustlings
cd rustlings
cargo install --force --path .
```
@@ -150,24 +150,6 @@ cargo uninstall rustlings
Now you should be done!
## Completion
Rustlings isn't done; there are a couple of sections that are very experimental and don't have proper documentation. These include:
- Errors (`exercises/errors/`)
- Option (`exercises/option/`)
- Result (`exercises/result/`)
- Move Semantics (could still be improved, `exercises/move_semantics/`)
Additionally, we could use exercises on a couple of topics:
- Structs
- Better ownership stuff
- `impl`
- ??? probably more
If you are interested in improving or adding new ones, please feel free to contribute! Read on for more information :)
## Contributing
See [CONTRIBUTING.md](./CONTRIBUTING.md).

View File

@@ -1,24 +1,26 @@
# Exercise to Book Chapter mapping
| Exercise | Book Chapter |
|------------------------|--------------|
| variables | §3.1 |
| functions | §3.3 |
| if | §3.5 |
| move_semantics | §4.1 |
| primitive_types | §4.3 |
| structs | §5.1 |
| enums | §6 |
| modules | §7 |
| collections | §8.1, §8.3 |
| strings | §8.2 |
| error_handling | §9 |
| generics | §10 |
| option | §10.1 |
| traits | §10.2 |
| tests | §11.1 |
| standard_library_types | §13.2 |
| threads | §16.1 |
| macros | §19.6 |
| clippy | n/a |
| conversions | n/a |
| Exercise | Book Chapter |
| ---------------------- | ------------------- |
| variables | §3.1 |
| functions | §3.3 |
| if | §3.5 |
| primitive_types | §3.2, §4.3 |
| vecs | §8.1 |
| move_semantics | §4.1, §4.2 |
| structs | §5.1, §5.3 |
| enums | §6, §18.3 |
| strings | §8.2 |
| modules | §7 |
| hashmaps | §8.3 |
| options | §10.1 |
| error_handling | §9 |
| generics | §10 |
| traits | §10.2 |
| tests | §11.1 |
| lifetimes | §10.3 |
| standard_library_types | §13.2, §15.1, §16.3 |
| threads | §16.1, §16.2, §16.3 |
| macros | §19.6 |
| clippy | n/a |
| conversions | n/a |

View File

@@ -1,98 +0,0 @@
// advanced_errs1.rs
// Remember back in errors6, we had multiple mapping functions so that we
// could translate lower-level errors into our custom error type using
// `map_err()`? What if we could use the `?` operator directly instead?
// Make this code compile! Execute `rustlings hint advanced_errs1` for
// hints :)
// I AM NOT DONE
use std::num::ParseIntError;
use std::str::FromStr;
// This is a custom error type that we will be using in the `FromStr`
// implementation.
#[derive(PartialEq, Debug)]
enum ParsePosNonzeroError {
Creation(CreationError),
ParseInt(ParseIntError),
}
impl From<CreationError> for ParsePosNonzeroError {
fn from(e: CreationError) -> Self {
// TODO: complete this implementation so that the `?` operator will
// work for `CreationError`
}
}
// TODO: implement another instance of the `From` trait here so that the
// `?` operator will work in the other place in the `FromStr`
// implementation below.
// Don't change anything below this line.
impl FromStr for PositiveNonzeroInteger {
type Err = ParsePosNonzeroError;
fn from_str(s: &str) -> Result<PositiveNonzeroInteger, Self::Err> {
let x: i64 = s.parse()?;
Ok(PositiveNonzeroInteger::new(x)?)
}
}
#[derive(PartialEq, Debug)]
struct PositiveNonzeroInteger(u64);
#[derive(PartialEq, Debug)]
enum CreationError {
Negative,
Zero,
}
impl PositiveNonzeroInteger {
fn new(value: i64) -> Result<PositiveNonzeroInteger, CreationError> {
match value {
x if x < 0 => Err(CreationError::Negative),
x if x == 0 => Err(CreationError::Zero),
x => Ok(PositiveNonzeroInteger(x as u64)),
}
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_parse_error() {
// We can't construct a ParseIntError, so we have to pattern match.
assert!(matches!(
PositiveNonzeroInteger::from_str("not a number"),
Err(ParsePosNonzeroError::ParseInt(_))
));
}
#[test]
fn test_negative() {
assert_eq!(
PositiveNonzeroInteger::from_str("-555"),
Err(ParsePosNonzeroError::Creation(CreationError::Negative))
);
}
#[test]
fn test_zero() {
assert_eq!(
PositiveNonzeroInteger::from_str("0"),
Err(ParsePosNonzeroError::Creation(CreationError::Zero))
);
}
#[test]
fn test_positive() {
let x = PositiveNonzeroInteger::new(42);
assert!(x.is_ok());
assert_eq!(PositiveNonzeroInteger::from_str("42"), Ok(x.unwrap()));
}
}

View File

@@ -1,202 +0,0 @@
// advanced_errs2.rs
// This exercise demonstrates a few traits that are useful for custom error
// types to implement, especially so that other code can consume the custom
// error type more usefully.
// Make this compile, and make the tests pass!
// Execute `rustlings hint advanced_errs2` for hints.
// Steps:
// 1. Implement a missing trait so that `main()` will compile.
// 2. Complete the partial implementation of `From` for
// `ParseClimateError`.
// 3. Handle the missing error cases in the `FromStr` implementation for
// `Climate`.
// 4. Complete the partial implementation of `Display` for
// `ParseClimateError`.
// I AM NOT DONE
use std::error::Error;
use std::fmt::{self, Display, Formatter};
use std::num::{ParseFloatError, ParseIntError};
use std::str::FromStr;
// This is the custom error type that we will be using for the parser for
// `Climate`.
#[derive(Debug, PartialEq)]
enum ParseClimateError {
Empty,
BadLen,
NoCity,
ParseInt(ParseIntError),
ParseFloat(ParseFloatError),
}
// This `From` implementation allows the `?` operator to work on
// `ParseIntError` values.
impl From<ParseIntError> for ParseClimateError {
fn from(e: ParseIntError) -> Self {
Self::ParseInt(e)
}
}
// This `From` implementation allows the `?` operator to work on
// `ParseFloatError` values.
impl From<ParseFloatError> for ParseClimateError {
fn from(e: ParseFloatError) -> Self {
// TODO: Complete this function
}
}
// TODO: Implement a missing trait so that `main()` below will compile. It
// is not necessary to implement any methods inside the missing trait.
// The `Display` trait allows for other code to obtain the error formatted
// as a user-visible string.
impl Display for ParseClimateError {
// TODO: Complete this function so that it produces the correct strings
// for each error variant.
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
// Imports the variants to make the following code more compact.
use ParseClimateError::*;
match self {
NoCity => write!(f, "no city name"),
ParseFloat(e) => write!(f, "error parsing temperature: {}", e),
}
}
}
#[derive(Debug, PartialEq)]
struct Climate {
city: String,
year: u32,
temp: f32,
}
// Parser for `Climate`.
// 1. Split the input string into 3 fields: city, year, temp.
// 2. Return an error if the string is empty or has the wrong number of
// fields.
// 3. Return an error if the city name is empty.
// 4. Parse the year as a `u32` and return an error if that fails.
// 5. Parse the temp as a `f32` and return an error if that fails.
// 6. Return an `Ok` value containing the completed `Climate` value.
impl FromStr for Climate {
type Err = ParseClimateError;
// TODO: Complete this function by making it handle the missing error
// cases.
fn from_str(s: &str) -> Result<Self, Self::Err> {
let v: Vec<_> = s.split(',').collect();
let (city, year, temp) = match &v[..] {
[city, year, temp] => (city.to_string(), year, temp),
_ => return Err(ParseClimateError::BadLen),
};
let year: u32 = year.parse()?;
let temp: f32 = temp.parse()?;
Ok(Climate { city, year, temp })
}
}
// Don't change anything below this line (other than to enable ignored
// tests).
fn main() -> Result<(), Box<dyn Error>> {
println!("{:?}", "Hong Kong,1999,25.7".parse::<Climate>()?);
println!("{:?}", "".parse::<Climate>()?);
Ok(())
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_empty() {
let res = "".parse::<Climate>();
assert_eq!(res, Err(ParseClimateError::Empty));
assert_eq!(res.unwrap_err().to_string(), "empty input");
}
#[test]
fn test_short() {
let res = "Boston,1991".parse::<Climate>();
assert_eq!(res, Err(ParseClimateError::BadLen));
assert_eq!(res.unwrap_err().to_string(), "incorrect number of fields");
}
#[test]
fn test_long() {
let res = "Paris,1920,17.2,extra".parse::<Climate>();
assert_eq!(res, Err(ParseClimateError::BadLen));
assert_eq!(res.unwrap_err().to_string(), "incorrect number of fields");
}
#[test]
fn test_no_city() {
let res = ",1997,20.5".parse::<Climate>();
assert_eq!(res, Err(ParseClimateError::NoCity));
assert_eq!(res.unwrap_err().to_string(), "no city name");
}
#[test]
fn test_parse_int_neg() {
let res = "Barcelona,-25,22.3".parse::<Climate>();
assert!(matches!(res, Err(ParseClimateError::ParseInt(_))));
let err = res.unwrap_err();
if let ParseClimateError::ParseInt(ref inner) = err {
assert_eq!(
err.to_string(),
format!("error parsing year: {}", inner.to_string())
);
} else {
unreachable!();
};
}
#[test]
fn test_parse_int_bad() {
let res = "Beijing,foo,15.0".parse::<Climate>();
assert!(matches!(res, Err(ParseClimateError::ParseInt(_))));
let err = res.unwrap_err();
if let ParseClimateError::ParseInt(ref inner) = err {
assert_eq!(
err.to_string(),
format!("error parsing year: {}", inner.to_string())
);
} else {
unreachable!();
};
}
#[test]
fn test_parse_float() {
let res = "Manila,2001,bar".parse::<Climate>();
assert!(matches!(res, Err(ParseClimateError::ParseFloat(_))));
let err = res.unwrap_err();
if let ParseClimateError::ParseFloat(ref inner) = err {
assert_eq!(
err.to_string(),
format!("error parsing temperature: {}", inner.to_string())
);
} else {
unreachable!();
};
}
#[test]
fn test_parse_good() {
let res = "Munich,2015,23.1".parse::<Climate>();
assert_eq!(
res,
Ok(Climate {
city: "Munich".to_string(),
year: 2015,
temp: 23.1,
})
);
}
#[test]
#[ignore]
fn test_downcast() {
let res = "São Paulo,-21,28.5".parse::<Climate>();
assert!(matches!(res, Err(ParseClimateError::ParseInt(_))));
let err = res.unwrap_err();
let inner: Option<&(dyn Error + 'static)> = err.source();
assert!(inner.is_some());
assert!(inner.unwrap().is::<ParseIntError>());
}
}

View File

@@ -1,2 +0,0 @@
mod advanced_errs1;
mod advanced_errs2;

View File

@@ -4,7 +4,7 @@
//
// For these exercises the code will fail to compile when there are clippy warnings
// check clippy's suggestions from the output to solve the exercise.
// Execute `rustlings hint clippy1` for hints :)
// Execute `rustlings hint clippy1` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE

View File

@@ -1,5 +1,5 @@
// clippy2.rs
// Make me compile! Execute `rustlings hint clippy2` for hints :)
// Execute `rustlings hint clippy2` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE

View File

@@ -0,0 +1,28 @@
// clippy3.rs
// Here's a couple more easy Clippy fixes, so you can see its utility.
// I AM NOT DONE
#[allow(unused_variables, unused_assignments)]
fn main() {
let my_option: Option<()> = None;
if my_option.is_none() {
my_option.unwrap();
}
let my_arr = &[
-1, -2, -3
-4, -5, -6
];
println!("My array! Here it is: {:?}", my_arr);
let my_empty_vec = vec![1, 2, 3, 4, 5].resize(0, 5);
println!("This Vec is empty, see? {:?}", my_empty_vec);
let mut value_a = 45;
let mut value_b = 66;
// Let's swap these two!
value_a = value_b;
value_b = value_a;
println!("value a: {}; value b: {}", value_a, value_b);
}

View File

@@ -1,2 +0,0 @@
mod clippy1;
mod clippy2;

View File

@@ -1,23 +0,0 @@
# Collections
Rust’s standard library includes a number of very useful data
structures called collections. Most other data types represent one
specific value, but collections can contain multiple values. Unlike
the built-in array and tuple types, the data these collections point
to is stored on the heap, which means the amount of data does not need
to be known at compile time and can grow or shrink as the program
runs.
This exercise will get you familiar with two fundamental data
structures that are used very often in Rust programs:
* A *vector* allows you to store a variable number of values next to
each other.
* 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),
[*dictionary* in Python](https://docs.python.org/3/tutorial/datastructures.html#dictionaries) or an *associative array* in other languages.
## Further information
- [Storing Lists of Values with Vectors](https://doc.rust-lang.org/stable/book/ch08-01-vectors.html)
- [Storing Keys with Associated Values in Hash Maps](https://doc.rust-lang.org/book/ch08-03-hash-maps.html)

View File

@@ -1,4 +0,0 @@
mod hashmap1;
mod hashmap2;
mod vec1;
mod vec2;

View File

@@ -1,6 +1,7 @@
// AsRef and AsMut allow for cheap reference-to-reference conversions.
// Read more about them at https://doc.rust-lang.org/std/convert/trait.AsRef.html
// and https://doc.rust-lang.org/std/convert/trait.AsMut.html, respectively.
// Execute `rustlings hint as_ref_mut` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE
@@ -16,10 +17,10 @@ fn char_counter<T>(arg: T) -> usize {
arg.as_ref().chars().count()
}
fn main() {
let s = "Café au lait";
println!("{}", char_counter(s));
println!("{}", byte_counter(s));
// Squares a number using AsMut. Add the trait bound as is appropriate and
// implement the function body.
fn num_sq<T>(arg: &mut T) {
???
}
#[cfg(test)]
@@ -49,4 +50,11 @@ mod tests {
let s = String::from("Cafe au lait");
assert_eq!(char_counter(s.clone()), byte_counter(s));
}
#[test]
fn mult_box() {
let mut num: Box<u32> = Box::new(3);
num_sq(&mut num);
assert_eq!(*num, 9);
}
}

View File

@@ -1,6 +1,8 @@
// The From trait is used for value-to-value conversions.
// If From is implemented correctly for a type, the Into trait should work conversely.
// You can read more about it at https://doc.rust-lang.org/std/convert/trait.From.html
// Execute `rustlings hint from_into` or use the `hint` watch subcommand for a hint.
#[derive(Debug)]
struct Person {
name: String,

View File

@@ -4,6 +4,8 @@
// Additionally, upon implementing FromStr, you can use the `parse` method
// on strings to generate an object of the implementor type.
// You can read more about it at https://doc.rust-lang.org/std/str/trait.FromStr.html
// Execute `rustlings hint from_str` or use the `hint` watch subcommand for a hint.
use std::num::ParseIntError;
use std::str::FromStr;
@@ -37,6 +39,9 @@ enum ParsePersonError {
// with something like `"4".parse::<usize>()`
// 6. If while extracting the name and the age something goes wrong, an error should be returned
// If everything goes well, then return a Result of a Person object
//
// As an aside: `Box<dyn Error>` implements `From<&'_ str>`. This means that if you want to return a
// string error message, you can do so via just using return `Err("my error message".into())`.
impl FromStr for Person {
type Err = ParsePersonError;

View File

@@ -1,5 +0,0 @@
mod as_ref_mut;
mod from_into;
mod from_str;
mod try_from_into;
mod using_as;

View File

@@ -3,6 +3,8 @@
// Basically, this is the same as From. The main difference is that this should return a Result type
// instead of the target type itself.
// You can read more about it at https://doc.rust-lang.org/std/convert/trait.TryFrom.html
// Execute `rustlings hint try_from_into` or use the `hint` watch subcommand for a hint.
use std::convert::{TryFrom, TryInto};
#[derive(Debug, PartialEq)]
@@ -54,7 +56,7 @@ impl TryFrom<&[i16]> for Color {
}
fn main() {
// Use the `from` function
// Use the `try_from` function
let c1 = Color::try_from((183, 65, 14));
println!("{:?}", c1);

View File

@@ -4,6 +4,7 @@
//
// The goal is to make sure that the division does not fail to compile
// and returns the proper type.
// Execute `rustlings hint using_as` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE

View File

@@ -1,5 +1,5 @@
// enums1.rs
// Make me compile! Execute `rustlings hint enums1` for hints!
// No hints this time! ;)
// I AM NOT DONE

View File

@@ -1,5 +1,5 @@
// enums2.rs
// Make me compile! Execute `rustlings hint enums2` for hints!
// Execute `rustlings hint enums2` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE

View File

@@ -1,5 +1,6 @@
// enums3.rs
// Address all the TODOs to make the tests pass!
// Execute `rustlings hint enums3` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE

View File

@@ -1,3 +0,0 @@
mod enums1;
mod enums2;
mod enums3;

View File

@@ -3,16 +3,16 @@
// you pass it an empty string. It'd be nicer if it explained what the problem
// was, instead of just sometimes returning `None`. Thankfully, Rust has a similar
// construct to `Option` that can be used to express error conditions. Let's use it!
// Execute `rustlings hint errors1` for hints!
// Execute `rustlings hint errors1` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE
pub fn generate_nametag_text(name: String) -> Option<String> {
if name.len() > 0 {
Some(format!("Hi! My name is {}", name))
} else {
if name.is_empty() {
// Empty names aren't allowed.
None
} else {
Some(format!("Hi! My name is {}", name))
}
}

View File

@@ -14,7 +14,8 @@
// and add.
// There are at least two ways to implement this that are both correct-- but
// one is a lot shorter! Execute `rustlings hint errors2` for hints to both ways.
// one is a lot shorter!
// Execute `rustlings hint errors2` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE

View File

@@ -2,7 +2,7 @@
// This is a program that is trying to use a completed version of the
// `total_cost` function from the previous exercise. It's not working though!
// Why not? What should we do to fix it?
// Execute `rustlings hint errors3` for hints!
// Execute `rustlings hint errors3` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE

View File

@@ -1,5 +1,5 @@
// errors4.rs
// Make this test pass! Execute `rustlings hint errors4` for hints :)
// Execute `rustlings hint errors4` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE
@@ -14,6 +14,7 @@ enum CreationError {
impl PositiveNonzeroInteger {
fn new(value: i64) -> Result<PositiveNonzeroInteger, CreationError> {
// Hmm...? Why is this only returning an Ok value?
Ok(PositiveNonzeroInteger(value as u64))
}
}

View File

@@ -1,8 +1,18 @@
// errors5.rs
// This program uses a completed version of the code from errors4.
// It won't compile right now! Why?
// Execute `rustlings hint errors5` for hints!
// This program uses an altered version of the code from errors4.
// This exercise uses some concepts that we won't get to until later in the course, like `Box` and the
// `From` trait. It's not important to understand them in detail right now, but you can read ahead if you like.
// In short, this particular use case for boxes is for when you want to own a value and you care only that it is a
// type which implements a particular trait. To do so, The Box is declared as of type Box<dyn Trait> where Trait is the trait
// the compiler looks for on any value used in that context. For this exercise, that context is the potential errors
// which can be returned in a Result.
// What can we use to describe both errors? In other words, is there a trait which both errors implement?
// Execute `rustlings hint errors5` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE
@@ -11,7 +21,7 @@ use std::fmt;
use std::num::ParseIntError;
// TODO: update the return type of `main()` to make this compile.
fn main() -> Result<(), ParseIntError> {
fn main() -> Result<(), Box<dyn ???>> {
let pretend_user_input = "42";
let x: i64 = pretend_user_input.parse()?;
println!("output={:?}", PositiveNonzeroInteger::new(x)?);

View File

@@ -6,7 +6,7 @@
// we define a custom error type to make it possible for callers to decide
// what to do next when our function returns an error.
// Make these tests pass! Execute `rustlings hint errors6` for hints :)
// Execute `rustlings hint errors6` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE
@@ -20,7 +20,11 @@ enum ParsePosNonzeroError {
}
impl ParsePosNonzeroError {
fn from_creation(err: CreationError) -> ParsePosNonzeroError {
ParsePosNonzeroError::Creation(err)
}
// TODO: add another error conversion function here.
// fn from_parseint...
}
fn parse_pos_nonzero(s: &str)

View File

@@ -1,6 +0,0 @@
mod errors1;
mod errors2;
mod errors3;
mod errors4;
mod errors5;
mod errors6;

View File

@@ -1,6 +1,7 @@
# Functions
Here, you'll learn how to write functions and how Rust's compiler can trace things way back.
Here, you'll learn how to write functions and how the Rust compiler can help you debug errors even
in more complex code.
## Further information

View File

@@ -1,5 +1,5 @@
// functions1.rs
// Make me compile! Execute `rustlings hint functions1` for hints :)
// Execute `rustlings hint functions1` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE

View File

@@ -1,5 +1,5 @@
// functions2.rs
// Make me compile! Execute `rustlings hint functions2` for hints :)
// Execute `rustlings hint functions2` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE

View File

@@ -1,5 +1,5 @@
// functions3.rs
// Make me compile! Execute `rustlings hint functions3` for hints :)
// Execute `rustlings hint functions3` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE

View File

@@ -1,8 +1,11 @@
// functions4.rs
// Make me compile! Execute `rustlings hint functions4` for hints :)
// Execute `rustlings hint functions4` or use the `hint` watch subcommand for a hint.
// This store is having a sale where if the price is an even number, you get
// 10 Rustbucks off, but if it's an odd number, it's 3 Rustbucks off.
// (Don't worry about the function bodies themselves, we're only interested
// in the signatures for now. If anything, this is a good way to peek ahead
// to future exercises!)
// I AM NOT DONE

View File

@@ -1,11 +1,11 @@
// functions5.rs
// Make me compile! Execute `rustlings hint functions5` for hints :)
// Execute `rustlings hint functions5` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE
fn main() {
let answer = square(3);
println!("The answer is {}", answer);
println!("The square of 3 is {}", answer);
}
fn square(num: i32) -> i32 {

View File

@@ -1,5 +0,0 @@
mod functions1;
mod functions2;
mod functions3;
mod functions4;
mod functions5;

View File

@@ -1,7 +1,7 @@
// This shopping list program isn't compiling!
// Use your knowledge of generics to fix it.
// Execute `rustlings hint generics1` for hints!
// Execute `rustlings hint generics1` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE

View File

@@ -1,7 +1,7 @@
// This powerful wrapper provides the ability to store a positive integer value.
// Rewrite it using generics so that it supports wrapping ANY type.
// Execute `rustlings hint generics2` for hints!
// Execute `rustlings hint generics2` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE

View File

@@ -1,58 +0,0 @@
// An imaginary magical school has a new report card generation system written in Rust!
// Currently the system only supports creating report cards where the student's grade
// is represented numerically (e.g. 1.0 -> 5.5).
// However, the school also issues alphabetical grades (A+ -> F-) and needs
// to be able to print both types of report card!
// Make the necessary code changes in the struct ReportCard and the impl block
// to support alphabetical report cards. Change the Grade in the second test to "A+"
// to show that your changes allow alphabetical grades.
// Execute 'rustlings hint generics3' for hints!
// I AM NOT DONE
pub struct ReportCard {
pub grade: f32,
pub student_name: String,
pub student_age: u8,
}
impl ReportCard {
pub fn print(&self) -> String {
format!("{} ({}) - achieved a grade of {}",
&self.student_name, &self.student_age, &self.grade)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn generate_numeric_report_card() {
let report_card = ReportCard {
grade: 2.1,
student_name: "Tom Wriggle".to_string(),
student_age: 12,
};
assert_eq!(
report_card.print(),
"Tom Wriggle (12) - achieved a grade of 2.1"
);
}
#[test]
fn generate_alphabetic_report_card() {
// TODO: Make sure to change the grade here after you finish the exercise.
let report_card = ReportCard {
grade: 2.1,
student_name: "Gary Plotter".to_string(),
student_age: 11,
};
assert_eq!(
report_card.print(),
"Gary Plotter (11) - achieved a grade of A+"
);
}
}

View File

@@ -1,3 +0,0 @@
mod generics1;
mod generics2;
mod generics3;

View File

@@ -0,0 +1,11 @@
# 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),
[*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
talking about Vecs.
## Further information
- [Storing Keys with Associated Values in Hash Maps](https://doc.rust-lang.org/book/ch08-03-hash-maps.html)

View File

@@ -1,4 +1,4 @@
// hashmap1.rs
// hashmaps1.rs
// A basket of fruits in the form of a hash map needs to be defined.
// The key represents the name of the fruit and the value represents
// how many of that particular fruit is in the basket. You have to put
@@ -8,8 +8,7 @@
//
// Make me compile and pass the tests!
//
// Execute the command `rustlings hint hashmap1` if you need
// hints.
// Execute `rustlings hint hashmaps1` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE

View File

@@ -1,4 +1,4 @@
// hashmap2.rs
// 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
@@ -9,8 +9,7 @@
//
// Make me pass the tests!
//
// Execute the command `rustlings hint hashmap2` if you need
// hints.
// Execute `rustlings hint hashmaps2` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE

View File

@@ -0,0 +1,87 @@
// hashmaps3.rs
// A list of scores (one per line) of a soccer match is given. Each line
// is of the form :
// <team_1_name>,<team_2_name>,<team_1_goals>,<team_2_goals>
// Example: England,France,4,2 (England scored 4 goals, France 2).
// You have to build a scores table containing the name of the team, goals
// the team scored, and goals the team conceded. One approach to build
// the scores table is to use a Hashmap. The solution is partially
// written to use a Hashmap, complete it to pass the test.
// Make me pass the tests!
// Execute `rustlings hint hashmaps3` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE
use std::collections::HashMap;
// A structure to store team name and its goal details.
struct Team {
name: String,
goals_scored: u8,
goals_conceded: u8,
}
fn build_scores_table(results: String) -> HashMap<String, Team> {
// The name of the team is the key and its associated struct is the value.
let mut scores: HashMap<String, Team> = HashMap::new();
for r in results.lines() {
let v: Vec<&str> = r.split(',').collect();
let team_1_name = v[0].to_string();
let team_1_score: u8 = v[2].parse().unwrap();
let team_2_name = v[1].to_string();
let team_2_score: u8 = v[3].parse().unwrap();
// TODO: Populate the scores table with details extracted from the
// current line. Keep in mind that goals scored by team_1
// will be number of goals conceded from team_2, and similarly
// goals scored by team_2 will be the number of goals conceded by
// team_1.
}
scores
}
#[cfg(test)]
mod tests {
use super::*;
fn get_results() -> String {
let results = "".to_string()
+ "England,France,4,2\n"
+ "France,Italy,3,1\n"
+ "Poland,Spain,2,0\n"
+ "Germany,England,2,1\n";
results
}
#[test]
fn build_scores() {
let scores = build_scores_table(get_results());
let mut keys: Vec<&String> = scores.keys().collect();
keys.sort();
assert_eq!(
keys,
vec!["England", "France", "Germany", "Italy", "Poland", "Spain"]
);
}
#[test]
fn validate_team_score_1() {
let scores = build_scores_table(get_results());
let team = scores.get("England").unwrap();
assert_eq!(team.goals_scored, 5);
assert_eq!(team.goals_conceded, 4);
}
#[test]
fn validate_team_score_2() {
let scores = build_scores_table(get_results());
let team = scores.get("Spain").unwrap();
assert_eq!(team.goals_scored, 0);
assert_eq!(team.goals_conceded, 2);
}
}

View File

@@ -1,6 +1,6 @@
# If
`if`, the most basic type of control flow, is what you'll learn here.
`if`, the most basic (but still surprisingly versatile!) type of control flow, is what you'll learn here.
## Further information

View File

@@ -1,4 +1,5 @@
// if1.rs
// Execute `rustlings hint if1` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE
@@ -7,7 +8,6 @@ pub fn bigger(a: i32, b: i32) -> i32 {
// Do not use:
// - another function call
// - additional variables
// Execute `rustlings hint if1` for hints
}
// Don't mind this for now :)

View File

@@ -2,11 +2,11 @@
// Step 1: Make me compile!
// Step 2: Get the bar_for_fuzz and default_to_baz tests passing!
// Execute the command `rustlings hint if2` if you want a hint :)
// Execute `rustlings hint if2` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE
pub fn fizz_if_foo(fizzish: &str) -> &str {
pub fn foo_if_fizz(fizzish: &str) -> &str {
if fizzish == "fizz" {
"foo"
} else {
@@ -21,16 +21,16 @@ mod tests {
#[test]
fn foo_for_fizz() {
assert_eq!(fizz_if_foo("fizz"), "foo")
assert_eq!(foo_if_fizz("fizz"), "foo")
}
#[test]
fn bar_for_fuzz() {
assert_eq!(fizz_if_foo("fuzz"), "bar")
assert_eq!(foo_if_fizz("fuzz"), "bar")
}
#[test]
fn default_to_baz() {
assert_eq!(fizz_if_foo("literally anything"), "baz")
assert_eq!(foo_if_fizz("literally anything"), "baz")
}
}

View File

@@ -1,2 +0,0 @@
mod if1;
mod if2;

View File

@@ -3,7 +3,11 @@
// We sometimes encourage you to keep trying things on a given exercise, even
// after you already figured it out. If you got everything working and feel
// ready for the next exercise, remove the `I AM NOT DONE` comment below.
// Execute the command `rustlings hint intro1` for a hint.
// Execute `rustlings hint intro1` or use the `hint` watch subcommand for a hint.
//
// If you're running this using `rustlings watch`: The exercise file will be reloaded
// when you change one of the lines below! Try adding a `println!` line, or try changing
// what it outputs in your terminal. Try removing a semicolon and see what happens!
// I AM NOT DONE
@@ -20,4 +24,7 @@ fn main() {
println!("This exercise compiles successfully. The remaining exercises contain a compiler");
println!("or logic error. The central concept behind Rustlings is to fix these errors and");
println!("solve the exercises. Good luck!");
println!();
println!("The source for this exercise is in `exercises/intro/intro1.rs`. Have a look!");
println!("Going forward, the source of the exercises will always be in the success/failure output.");
}

View File

@@ -1,6 +1,6 @@
// intro2.rs
// Make the code print a greeting to the world.
// Execute `rustlings hint intro2` for a hint.
// Execute `rustlings hint intro2` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE

View File

@@ -1,2 +0,0 @@
mod intro1;
mod intro2;

View File

@@ -0,0 +1,17 @@
# Lifetimes
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".
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
restrictive of their callers.
## 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)

View File

@@ -0,0 +1,26 @@
// lifetimes1.rs
//
// The Rust compiler needs to know how to check whether supplied references are
// valid, so that it can let the programmer know if a reference is at risk
// of going out of scope before it is used. Remember, references are borrows
// and do not own their own data. What if their owner goes out of scope?
//
// Execute `rustlings hint lifetimes1` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE
fn longest(x: &str, y: &str) -> &str {
if x.len() > y.len() {
x
} else {
y
}
}
fn main() {
let string1 = String::from("abcd");
let string2 = "xyz";
let result = longest(string1.as_str(), string2);
println!("The longest string is {}", result);
}

View File

@@ -0,0 +1,27 @@
// lifetimes2.rs
//
// So if the compiler is just validating the references passed
// to the annotated parameters and the return type, what do
// we need to change?
//
// Execute `rustlings hint lifetimes2` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() {
x
} else {
y
}
}
fn main() {
let string1 = String::from("long string is long");
let result;
{
let string2 = String::from("xyz");
result = longest(string1.as_str(), string2.as_str());
}
println!("The longest string is {}", result);
}

View File

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

View File

@@ -1,5 +1,5 @@
// macros1.rs
// Make me compile! Execute `rustlings hint macros1` for hints :)
// Execute `rustlings hint macros1` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE

View File

@@ -1,5 +1,5 @@
// macros2.rs
// Make me compile! Execute `rustlings hint macros2` for hints :)
// Execute `rustlings hint macros2` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE

View File

@@ -1,6 +1,6 @@
// macros3.rs
// Make me compile, without taking the macro out of the module!
// Execute `rustlings hint macros3` for hints :)
// Execute `rustlings hint macros3` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE

View File

@@ -1,5 +1,5 @@
// macros4.rs
// Make me compile! Execute `rustlings hint macros4` for hints :)
// Execute `rustlings hint macros4` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE

View File

@@ -1,4 +0,0 @@
mod macros1;
mod macros2;
mod macros3;
mod macros4;

View File

@@ -1,26 +0,0 @@
mod advanced_errors;
mod clippy;
mod collections;
mod conversions;
mod enums;
mod error_handling;
mod functions;
mod generics;
mod r#if;
mod intro;
mod macros;
mod modules;
mod move_semantics;
mod option;
mod primitive_types;
mod quiz1;
mod quiz2;
mod quiz3;
mod quiz4;
mod standard_library_types;
mod strings;
mod structs;
mod tests;
mod threads;
mod traits;
mod variables;

View File

@@ -1,3 +0,0 @@
mod modules1;
mod modules2;
mod modules3;

View File

@@ -1,5 +1,5 @@
// modules1.rs
// Make me compile! Execute `rustlings hint modules1` for hints :)
// Execute `rustlings hint modules1` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE

View File

@@ -1,12 +1,11 @@
// modules2.rs
// You can bring module paths into scopes and provide new names for them with the
// 'use' and 'as' keywords. Fix these 'use' statements to make the code compile.
// Make me compile! Execute `rustlings hint modules2` for hints :)
// Execute `rustlings hint modules2` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE
mod delicious_snacks {
// TODO: Fix these use statements
use self::fruits::PEAR as ???
use self::veggies::CUCUMBER as ???

View File

@@ -3,7 +3,7 @@
// and especially from the Rust standard library into your scope.
// Bring SystemTime and UNIX_EPOCH
// from the std::time module. Bonus style points if you can do it with one line!
// Make me compile! Execute `rustlings hint modules3` for hints :)
// Execute `rustlings hint modules3` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE

View File

@@ -1,6 +0,0 @@
mod move_semantics1;
mod move_semantics2;
mod move_semantics3;
mod move_semantics4;
mod move_semantics5;
mod move_semantics6;

View File

@@ -1,5 +1,5 @@
// move_semantics1.rs
// Make me compile! Execute `rustlings hint move_semantics1` for hints :)
// Execute `rustlings hint move_semantics1` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE

View File

@@ -1,6 +1,6 @@
// move_semantics2.rs
// Make me compile without changing line 13 or moving line 10!
// Execute `rustlings hint move_semantics2` for hints :)
// Execute `rustlings hint move_semantics2` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE

View File

@@ -1,7 +1,7 @@
// move_semantics3.rs
// Make me compile without adding new lines-- just changing existing lines!
// (no lines with multiple semicolons necessary!)
// Execute `rustlings hint move_semantics3` for hints :)
// Execute `rustlings hint move_semantics3` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE

View File

@@ -1,8 +1,8 @@
// move_semantics4.rs
// Refactor this code so that instead of having `vec0` and creating the vector
// in `fn main`, we create it within `fn fill_vec` and transfer the
// freshly created vector from fill_vec to its caller.
// Execute `rustlings hint move_semantics4` for hints!
// Refactor this code so that instead of passing `vec0` into the `fill_vec` function,
// the Vector gets created in the function itself and passed back to the main
// function.
// Execute `rustlings hint move_semantics4` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE

View File

@@ -1,7 +1,7 @@
// move_semantics5.rs
// Make me compile only by reordering the lines in `main()`, but without
// adding, changing or removing any of them.
// Execute `rustlings hint move_semantics5` for hints :)
// Execute `rustlings hint move_semantics5` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE

View File

@@ -1,6 +1,6 @@
// move_semantics6.rs
// Make me compile! `rustlings hint move_semantics6` for hints
// You can't change anything except adding or removing references
// Execute `rustlings hint move_semantics6` or use the `hint` watch subcommand for a hint.
// You can't change anything except adding or removing references.
// I AM NOT DONE

View File

@@ -1,3 +0,0 @@
mod option1;
mod option2;
mod option3;

View File

@@ -1,23 +0,0 @@
// option1.rs
// Make me compile! Execute `rustlings hint option1` for hints
// I AM NOT DONE
// you can modify anything EXCEPT for this function's signature
fn print_number(maybe_number: Option<u16>) {
println!("printing: {}", maybe_number.unwrap());
}
fn main() {
print_number(13);
print_number(99);
let mut numbers: [Option<u16>; 5];
for iter in 0..5 {
let number_to_add: u16 = {
((iter * 1235) + 2) / (4 * 16)
};
numbers[iter as usize] = number_to_add;
}
}

View File

@@ -1,4 +1,4 @@
# Option
# Options
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:

View File

@@ -0,0 +1,37 @@
// options1.rs
// Execute `rustlings hint options1` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE
// you can modify anything EXCEPT for this function's signature
fn print_number(maybe_number: Option<u16>) {
println!("printing: {}", maybe_number.unwrap());
}
// This function returns how much icecream there is left in the fridge.
// If it's before 10PM, there's 5 pieces left. At 10PM, someone eats them
// all, so there'll be no more left :(
// TODO: Return an Option!
fn maybe_icecream(time_of_day: u16) -> Option<u16> {
// We use the 24-hour system here, so 10PM is a value of 22
???
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn check_icecream() {
assert_eq!(maybe_icecream(10), Some(5));
assert_eq!(maybe_icecream(23), None);
assert_eq!(maybe_icecream(22), None);
}
#[test]
fn raw_value() {
// TODO: Fix this test. How do you get at the value contained in the Option?
let icecreams = maybe_icecream(12);
assert_eq!(icecreams, 5);
}
}

View File

@@ -1,5 +1,5 @@
// option2.rs
// Make me compile! Execute `rustlings hint option2` for hints
// options2.rs
// Execute `rustlings hint options2` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE

View File

@@ -1,5 +1,5 @@
// option3.rs
// Make me compile! Execute `rustlings hint option3` for hints
// options3.rs
// Execute `rustlings hint options3` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE

View File

@@ -1,6 +0,0 @@
mod primitive_types1;
mod primitive_types2;
mod primitive_types3;
mod primitive_types4;
mod primitive_types5;
mod primitive_types6;

View File

@@ -7,6 +7,8 @@
fn main() {
// Characters (`char`)
// Note the _single_ quotes, these are different from the double quotes
// you've been seeing around.
let my_first_initial = 'C';
if my_first_initial.is_alphabetic() {
println!("Alphabetical!");

View File

@@ -1,6 +1,6 @@
// primitive_types3.rs
// Create an array with at least 100 elements in it where the ??? is.
// Execute `rustlings hint primitive_types3` for hints!
// Execute `rustlings hint primitive_types3` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE

View File

@@ -1,6 +1,6 @@
// primitive_types4.rs
// Get a slice out of Array a where the ??? is so that the test passes.
// Execute `rustlings hint primitive_types4` for hints!!
// Execute `rustlings hint primitive_types4` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE

View File

@@ -1,6 +1,6 @@
// primitive_types5.rs
// Destructure the `cat` tuple so that the println will work.
// Execute `rustlings hint primitive_types5` for hints!
// Execute `rustlings hint primitive_types5` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE

View File

@@ -1,7 +1,7 @@
// primitive_types6.rs
// Use a tuple index to access the second element of `numbers`.
// You can put the expression for the second element where ??? is so that the test passes.
// Execute `rustlings hint primitive_types6` for hints!
// Execute `rustlings hint primitive_types6` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE

View File

@@ -11,14 +11,14 @@
// I AM NOT DONE
// Put your function here!
// fn calculate_apple_price {
// fn calculate_price_of_apples {
// Don't modify this function!
#[test]
fn verify_test() {
let price1 = calculate_apple_price(35);
let price2 = calculate_apple_price(40);
let price3 = calculate_apple_price(65);
let price1 = calculate_price_of_apples(35);
let price2 = calculate_price_of_apples(40);
let price3 = calculate_price_of_apples(65);
assert_eq!(70, price1);
assert_eq!(80, price2);

View File

@@ -1,30 +1,62 @@
// quiz2.rs
// This is a quiz for the following sections:
// - Strings
// - Vecs
// - Move semantics
// - Modules
// - Enums
// Ok, here are a bunch of values-- some are `String`s, some are `&str`s. Your
// task is to call one of these two functions on each value depending on what
// you think each value is. That is, add either `string_slice` or `string`
// before the parentheses on each line. If you're right, it will compile!
// Let's build a little machine in form of a function.
// As input, we're going to give a list of strings and commands. These commands
// determine what action is going to be applied to the string. It can either be:
// - Uppercase the string
// - Trim the string
// - Append "bar" to the string a specified amount of times
// The exact form of this will be:
// - The input is going to be a Vector of a 2-length tuple,
// the first element is the string, the second one is the command.
// - The output element is going to be a Vector of strings.
// Execute `rustlings hint quiz2` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE
fn string_slice(arg: &str) {
println!("{}", arg);
}
fn string(arg: String) {
println!("{}", arg);
pub enum Command {
Uppercase,
Trim,
Append(usize),
}
fn main() {
???("blue");
???("red".to_string());
???(String::from("hi"));
???("rust is fun!".to_owned());
???("nice weather".into());
???(format!("Interpolation {}", "Station"));
???(&String::from("abc")[0..1]);
???(" hello there ".trim());
???("Happy Monday!".to_string().replace("Mon", "Tues"));
???("mY sHiFt KeY iS sTiCkY".to_lowercase());
mod my_module {
use super::Command;
// TODO: Complete the function signature!
pub fn transformer(input: ???) -> ??? {
// TODO: Complete the output declaration!
let mut output: ??? = vec![];
for (string, command) in input.iter() {
// TODO: Complete the function body. You can do it!
}
output
}
}
#[cfg(test)]
mod tests {
// TODO: What to we have to import to have `transformer` in scope?
use ???;
use super::Command;
#[test]
fn it_works() {
let output = transformer(vec![
("hello".into(), Command::Uppercase),
(" all roads lead to rome! ".into(), Command::Trim),
("foo".into(), Command::Append(1)),
("bar".into(), Command::Append(5)),
]);
assert_eq!(output[0], "HELLO");
assert_eq!(output[1], "all roads lead to rome!");
assert_eq!(output[2], "foobar");
assert_eq!(output[3], "barbarbarbarbarbar");
}
}

View File

@@ -1,16 +1,32 @@
// quiz3.rs
// This is a quiz for the following sections:
// - Tests
// This quiz tests:
// - Generics
// - Traits
// An imaginary magical school has a new report card generation system written in Rust!
// Currently the system only supports creating report cards where the student's grade
// is represented numerically (e.g. 1.0 -> 5.5).
// However, the school also issues alphabetical grades (A+ -> F-) and needs
// to be able to print both types of report card!
// This quiz isn't testing our function -- make it do that in such a way that
// the test passes. Then write a second test that tests that we get the result
// we expect to get when we call `times_two` with a negative number.
// No hints, you can do this :)
// Make the necessary code changes in the struct ReportCard and the impl block
// to support alphabetical report cards. Change the Grade in the second test to "A+"
// to show that your changes allow alphabetical grades.
// Execute `rustlings hint quiz3` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE
pub fn times_two(num: i32) -> i32 {
num * 2
pub struct ReportCard {
pub grade: f32,
pub student_name: String,
pub student_age: u8,
}
impl ReportCard {
pub fn print(&self) -> String {
format!("{} ({}) - achieved a grade of {}",
&self.student_name, &self.student_age, &self.grade)
}
}
#[cfg(test)]
@@ -18,13 +34,29 @@ mod tests {
use super::*;
#[test]
fn returns_twice_of_positive_numbers() {
assert_eq!(times_two(4), ???);
fn generate_numeric_report_card() {
let report_card = ReportCard {
grade: 2.1,
student_name: "Tom Wriggle".to_string(),
student_age: 12,
};
assert_eq!(
report_card.print(),
"Tom Wriggle (12) - achieved a grade of 2.1"
);
}
#[test]
fn returns_twice_of_negative_numbers() {
// TODO replace unimplemented!() with an assert for `times_two(-4)`
unimplemented!()
fn generate_alphabetic_report_card() {
// TODO: Make sure to change the grade here after you finish the exercise.
let report_card = ReportCard {
grade: 2.1,
student_name: "Gary Plotter".to_string(),
student_age: 11,
};
assert_eq!(
report_card.print(),
"Gary Plotter (11) - achieved a grade of A+"
);
}
}

View File

@@ -1,23 +0,0 @@
// quiz4.rs
// This quiz covers the sections:
// - Modules
// - Macros
// Write a macro that passes the quiz! No hints this time, you can do it!
// I AM NOT DONE
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_my_macro_world() {
assert_eq!(my_macro!("world!"), "Hello world!");
}
#[test]
fn test_my_macro_goodbye() {
assert_eq!(my_macro!("goodbye!"), "Hello goodbye!");
}
}

View File

@@ -16,7 +16,7 @@
// Make this code compile by filling in a value for `shared_numbers` where the
// first TODO comment is, and create an initial binding for `child_numbers`
// where the second TODO comment is. Try not to create any copies of the `numbers` Vec!
// Execute `rustlings hint arc1` for hints :)
// Execute `rustlings hint arc1` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE

View File

@@ -14,7 +14,7 @@
//
// Note: the tests should not be changed
//
// Execute `rustlings hint box1` for hints :)
// Execute `rustlings hint box1` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE

View File

@@ -6,7 +6,7 @@
// This module helps you get familiar with the structure of using an iterator and
// how to go through elements within an iterable collection.
//
// Execute `rustlings hint iterators1` for hints :D
// Execute `rustlings hint iterators1` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE

View File

@@ -1,7 +1,7 @@
// iterators2.rs
// In this exercise, you'll learn some of the unique advantages that iterators
// can offer. Follow the steps to complete the exercise.
// As always, there are hints if you execute `rustlings hint iterators2`!
// Execute `rustlings hint iterators2` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE

View File

@@ -4,7 +4,7 @@
// 1. Complete the divide function to get the first four tests to pass.
// 2. Get the remaining tests to pass by completing the result_with_list and
// list_of_results functions.
// Execute `rustlings hint iterators3` to get some hints!
// Execute `rustlings hint iterators3` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE
@@ -22,7 +22,9 @@ pub struct NotDivisibleError {
// Calculate `a` divided by `b` if `a` is evenly divisible by `b`.
// Otherwise, return a suitable error.
pub fn divide(a: i32, b: i32) -> Result<i32, DivisionError> {}
pub fn divide(a: i32, b: i32) -> Result<i32, DivisionError> {
todo!();
}
// Complete the function and return a value of the correct type so the test passes.
// Desired output: Ok([1, 11, 1426, 3])

Some files were not shown because too many files have changed in this diff Show More