1
0
Fork 0
mirror of https://github.com/rust-lang/rustlings.git synced 2024-05-10 00:26:07 +02:00

Merge remote-tracking branch 'origin/main'

This commit is contained in:
wznmickey 2024-03-28 00:11:19 +08:00
commit dd72429af4
26 changed files with 767 additions and 515 deletions

View File

@ -2559,6 +2559,132 @@
"contributions": [
"content"
]
},
{
"login": "AnonimAnonim2245",
"name": "Luca Plian",
"avatar_url": "https://avatars.githubusercontent.com/u/98339220?v=4",
"profile": "https://github.com/AnonimAnonim2245",
"contributions": [
"code"
]
},
{
"login": "reifenrath-dev",
"name": "RenΓ© Reifenrath",
"avatar_url": "https://avatars.githubusercontent.com/u/18126097?v=4",
"profile": "https://reifenrath.dev/",
"contributions": [
"content"
]
},
{
"login": "peterneave",
"name": "Peter Neave",
"avatar_url": "https://avatars.githubusercontent.com/u/7982708?v=4",
"profile": "https://github.com/peterneave",
"contributions": [
"infra"
]
},
{
"login": "JanB1",
"name": "Jan",
"avatar_url": "https://avatars.githubusercontent.com/u/5552248?v=4",
"profile": "http://www.janb1.com",
"contributions": [
"content"
]
},
{
"login": "kylev",
"name": "Kyle VanderBeek",
"avatar_url": "https://avatars.githubusercontent.com/u/46888?v=4",
"profile": "http://www.kylev.com/",
"contributions": [
"infra"
]
},
{
"login": "pavedroad",
"name": "pavedroad",
"avatar_url": "https://avatars.githubusercontent.com/u/138004431?v=4",
"profile": "https://github.com/pavedroad",
"contributions": [
"content"
]
},
{
"login": "hyphena",
"name": "luna",
"avatar_url": "https://avatars.githubusercontent.com/u/26529488?v=4",
"profile": "https://github.com/hyphena",
"contributions": [
"content"
]
},
{
"login": "evanmiller2112",
"name": "Evan Miller",
"avatar_url": "https://avatars.githubusercontent.com/u/28488957?v=4",
"profile": "https://github.com/evanmiller2112",
"contributions": [
"content"
]
},
{
"login": "luvchurchill",
"name": "luvchurchill",
"avatar_url": "https://avatars.githubusercontent.com/u/46406654?v=4",
"profile": "https://github.com/luvchurchill",
"contributions": [
"code"
]
},
{
"login": "LeverImmy",
"name": "Ze-en Xiong",
"avatar_url": "https://avatars.githubusercontent.com/u/47663913?v=4",
"profile": "https://leverimmy.top/",
"contributions": [
"content"
]
},
{
"login": "parnavh",
"name": "Parnav Harinathan",
"avatar_url": "https://avatars.githubusercontent.com/u/45985534?v=4",
"profile": "https://github.com/parnavh",
"contributions": [
"content"
]
},
{
"login": "0Ahmed-0",
"name": "0Ahmed-0",
"avatar_url": "https://avatars.githubusercontent.com/u/111569638?v=4",
"profile": "https://github.com/0Ahmed-0",
"contributions": [
"content"
]
},
{
"login": "guizo792",
"name": "guizo792",
"avatar_url": "https://avatars.githubusercontent.com/u/95940388?v=4",
"profile": "https://github.com/guizo792",
"contributions": [
"content"
]
},
{
"login": "kazu728",
"name": "Kazuki Matsuo",
"avatar_url": "https://avatars.githubusercontent.com/u/34614358?v=4",
"profile": "https://github.com/kazu728",
"contributions": [
"code"
]
}
],
"contributorsPerLine": 8,

View File

@ -1,17 +1,8 @@
{
"image": "mcr.microsoft.com/devcontainers/universal:2-linux",
"waitFor": "onCreateCommand",
"onCreateCommand": ".devcontainer/setup.sh",
"updateContentCommand": "cargo build",
"postCreateCommand": "",
"postAttachCommand": {
"server": "rustlings watch"
},
"customizations": {
"vscode": {
"extensions": [
"rust-lang.rust-analyzer"
]
}
"image": "mcr.microsoft.com/devcontainers/rust:1",
"updateContentCommand": ["cargo", "build"],
"postAttachCommand": ["rustlings", "watch"],
"remoteEnv": {
"PATH": "${containerEnv:PATH}:${containerWorkspaceFolder}/target/debug"
}
}

View File

@ -1,7 +0,0 @@
#!/bin/bash
curl https://sh.rustup.rs -sSf | sh -s -- -y
# Update current shell environment variables after install to find rustup
. "$HOME/.cargo/env"
rustup install stable
bash install.sh

2
.gitattributes vendored Normal file
View File

@ -0,0 +1,2 @@
* text=auto
*.sh text eol=lf

View File

@ -362,6 +362,22 @@ authors.
</tr>
<tr>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/gerases"><img src="https://avatars.githubusercontent.com/u/8953623?v=4?s=100" width="100px;" alt="gerases"/><br /><sub><b>gerases</b></sub></a><br /><a href="#content-gerases" title="Content">πŸ–‹</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/AnonimAnonim2245"><img src="https://avatars.githubusercontent.com/u/98339220?v=4?s=100" width="100px;" alt="Luca Plian"/><br /><sub><b>Luca Plian</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=AnonimAnonim2245" title="Code">πŸ’»</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://reifenrath.dev/"><img src="https://avatars.githubusercontent.com/u/18126097?v=4?s=100" width="100px;" alt="RenΓ© Reifenrath"/><br /><sub><b>RenΓ© Reifenrath</b></sub></a><br /><a href="#content-reifenrath-dev" title="Content">πŸ–‹</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/peterneave"><img src="https://avatars.githubusercontent.com/u/7982708?v=4?s=100" width="100px;" alt="Peter Neave"/><br /><sub><b>Peter Neave</b></sub></a><br /><a href="#infra-peterneave" title="Infrastructure (Hosting, Build-Tools, etc)">πŸš‡</a></td>
<td align="center" valign="top" width="12.5%"><a href="http://www.janb1.com"><img src="https://avatars.githubusercontent.com/u/5552248?v=4?s=100" width="100px;" alt="Jan"/><br /><sub><b>Jan</b></sub></a><br /><a href="#content-JanB1" title="Content">πŸ–‹</a></td>
<td align="center" valign="top" width="12.5%"><a href="http://www.kylev.com/"><img src="https://avatars.githubusercontent.com/u/46888?v=4?s=100" width="100px;" alt="Kyle VanderBeek"/><br /><sub><b>Kyle VanderBeek</b></sub></a><br /><a href="#infra-kylev" title="Infrastructure (Hosting, Build-Tools, etc)">πŸš‡</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/pavedroad"><img src="https://avatars.githubusercontent.com/u/138004431?v=4?s=100" width="100px;" alt="pavedroad"/><br /><sub><b>pavedroad</b></sub></a><br /><a href="#content-pavedroad" title="Content">πŸ–‹</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/hyphena"><img src="https://avatars.githubusercontent.com/u/26529488?v=4?s=100" width="100px;" alt="luna"/><br /><sub><b>luna</b></sub></a><br /><a href="#content-hyphena" title="Content">πŸ–‹</a></td>
</tr>
<tr>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/evanmiller2112"><img src="https://avatars.githubusercontent.com/u/28488957?v=4?s=100" width="100px;" alt="Evan Miller"/><br /><sub><b>Evan Miller</b></sub></a><br /><a href="#content-evanmiller2112" title="Content">πŸ–‹</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/luvchurchill"><img src="https://avatars.githubusercontent.com/u/46406654?v=4?s=100" width="100px;" alt="luvchurchill"/><br /><sub><b>luvchurchill</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=luvchurchill" title="Code">πŸ’»</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://leverimmy.top/"><img src="https://avatars.githubusercontent.com/u/47663913?v=4?s=100" width="100px;" alt="Ze-en Xiong"/><br /><sub><b>Ze-en Xiong</b></sub></a><br /><a href="#content-LeverImmy" title="Content">πŸ–‹</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/parnavh"><img src="https://avatars.githubusercontent.com/u/45985534?v=4?s=100" width="100px;" alt="Parnav Harinathan"/><br /><sub><b>Parnav Harinathan</b></sub></a><br /><a href="#content-parnavh" title="Content">πŸ–‹</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/0Ahmed-0"><img src="https://avatars.githubusercontent.com/u/111569638?v=4?s=100" width="100px;" alt="0Ahmed-0"/><br /><sub><b>0Ahmed-0</b></sub></a><br /><a href="#content-0Ahmed-0" title="Content">πŸ–‹</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/guizo792"><img src="https://avatars.githubusercontent.com/u/95940388?v=4?s=100" width="100px;" alt="guizo792"/><br /><sub><b>guizo792</b></sub></a><br /><a href="#content-guizo792" title="Content">πŸ–‹</a></td>
<td align="center" valign="top" width="12.5%"><a href="https://github.com/kazu728"><img src="https://avatars.githubusercontent.com/u/34614358?v=4?s=100" width="100px;" alt="Kazuki Matsuo"/><br /><sub><b>Kazuki Matsuo</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=kazu728" title="Code">πŸ’»</a></td>
</tr>
</tbody>
</table>

View File

@ -167,7 +167,7 @@
- **structs3**: Clarifed the hint
- **quiz2, as_ref_mut, options1, traits1, traits2**: Clarified hints
- **traits1, traits2, cli**: Tidied up unmatching backticks
- **enums2**: Removed unneccessary indirection of self
- **enums2**: Removed unnecessary indirection of self
- **enums3**: Added an extra tuple comment
#### Housekeeping

417
Cargo.lock generated
View File

@ -4,18 +4,18 @@ version = 3
[[package]]
name = "aho-corasick"
version = "0.7.20"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac"
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
dependencies = [
"memchr",
]
[[package]]
name = "anstream"
version = "0.5.0"
version = "0.6.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1f58811cfac344940f1a400b6e6231ce35171f614f26439e80f8c1465c5cc0c"
checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb"
dependencies = [
"anstyle",
"anstyle-parse",
@ -27,43 +27,49 @@ dependencies = [
[[package]]
name = "anstyle"
version = "1.0.3"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b84bf0a05bbb2a83e5eb6fa36bb6e87baa08193c35ff52bbf6b38d8af2890e46"
checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc"
[[package]]
name = "anstyle-parse"
version = "0.2.1"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333"
checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.0.0"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b"
checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648"
dependencies = [
"windows-sys 0.48.0",
"windows-sys 0.52.0",
]
[[package]]
name = "anstyle-wincon"
version = "2.1.0"
version = "3.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "58f54d10c6dfa51283a066ceab3ec1ab78d13fae00aa49243a45e4571fb79dfd"
checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7"
dependencies = [
"anstyle",
"windows-sys 0.48.0",
"windows-sys 0.52.0",
]
[[package]]
name = "assert_cmd"
version = "2.0.12"
name = "anyhow"
version = "1.0.81"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88903cb14723e4d4003335bb7f8a14f27691649105346a0f0957466c096adfe6"
checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247"
[[package]]
name = "assert_cmd"
version = "2.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed72493ac66d5804837f480ab3766c72bdfab91a65e565fc54fa9e42db0073a8"
dependencies = [
"anstyle",
"bstr",
@ -76,9 +82,9 @@ dependencies = [
[[package]]
name = "autocfg"
version = "1.1.0"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80"
[[package]]
name = "bitflags"
@ -88,15 +94,15 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
version = "2.4.1"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07"
checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
[[package]]
name = "bstr"
version = "1.6.2"
version = "1.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c2f7349907b712260e64b0afe2f84692af14a454be26187d9df565c7f69266a"
checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706"
dependencies = [
"memchr",
"regex-automata",
@ -111,9 +117,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
version = "4.4.3"
version = "4.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "84ed82781cea27b43c9b106a979fe450a13a31aab0500595fb3fc06616de08e6"
checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0"
dependencies = [
"clap_builder",
"clap_derive",
@ -121,9 +127,9 @@ dependencies = [
[[package]]
name = "clap_builder"
version = "4.4.2"
version = "4.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2bb9faaa7c2ef94b2743a21f5a29e6f0010dff4caa69ac8e9d6cf8b6fa74da08"
checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4"
dependencies = [
"anstream",
"anstyle",
@ -133,9 +139,9 @@ dependencies = [
[[package]]
name = "clap_derive"
version = "4.4.2"
version = "4.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873"
checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64"
dependencies = [
"heck",
"proc-macro2",
@ -145,9 +151,9 @@ dependencies = [
[[package]]
name = "clap_lex"
version = "0.5.1"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961"
checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce"
[[package]]
name = "colorchoice"
@ -157,35 +163,31 @@ checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
[[package]]
name = "console"
version = "0.15.5"
version = "0.15.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3d79fbe8970a77e3e34151cc13d3b3e248aa0faaecb9f6091fa07ebefe5ad60"
checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb"
dependencies = [
"encode_unicode",
"lazy_static",
"libc",
"unicode-width",
"windows-sys 0.42.0",
"windows-sys 0.52.0",
]
[[package]]
name = "crossbeam-channel"
version = "0.5.8"
version = "0.5.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200"
checksum = "ab3db02a9c5b5121e1e42fbdb1aeb65f5e02624cc58c43f2884c6ccac0b82f95"
dependencies = [
"cfg-if",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.16"
version = "0.8.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294"
dependencies = [
"cfg-if",
]
checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345"
[[package]]
name = "difflib"
@ -201,9 +203,9 @@ checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10"
[[package]]
name = "either"
version = "1.9.0"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a"
[[package]]
name = "encode_unicode"
@ -218,15 +220,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "filetime"
version = "0.2.22"
name = "errno"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4029edd3e734da6fe05b6cd7bd2960760a616bd2ddd0d59a0124746d6272af0"
checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245"
dependencies = [
"libc",
"windows-sys 0.52.0",
]
[[package]]
name = "filetime"
version = "0.2.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd"
dependencies = [
"cfg-if",
"libc",
"redox_syscall",
"windows-sys 0.48.0",
"windows-sys 0.52.0",
]
[[package]]
@ -255,30 +267,30 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
[[package]]
name = "hashbrown"
version = "0.14.0"
version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a"
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
[[package]]
name = "heck"
version = "0.4.1"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "home"
version = "0.5.4"
version = "0.5.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "747309b4b440c06d57b0b25f2aee03ee9b5e5397d288c60e21fc709bb98a7408"
checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5"
dependencies = [
"winapi",
"windows-sys 0.52.0",
]
[[package]]
name = "indexmap"
version = "2.0.0"
version = "2.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d"
checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26"
dependencies = [
"equivalent",
"hashbrown",
@ -286,9 +298,9 @@ dependencies = [
[[package]]
name = "indicatif"
version = "0.17.6"
version = "0.17.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b297dc40733f23a0e52728a58fa9489a5b7638a324932de16b41adc3ef80730"
checksum = "763a5a8f45087d6bcea4222e7b72c291a054edf80e4ef6efd2a4979878c7bea3"
dependencies = [
"console",
"instant",
@ -326,20 +338,11 @@ dependencies = [
"cfg-if",
]
[[package]]
name = "itertools"
version = "0.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
dependencies = [
"either",
]
[[package]]
name = "itoa"
version = "1.0.6"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
[[package]]
name = "kqueue"
@ -369,30 +372,33 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.150"
version = "0.2.153"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c"
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
[[package]]
name = "linux-raw-sys"
version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c"
[[package]]
name = "log"
version = "0.4.17"
version = "0.4.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
dependencies = [
"cfg-if",
]
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
[[package]]
name = "memchr"
version = "2.6.3"
version = "2.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c"
checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
[[package]]
name = "mio"
version = "0.8.9"
version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0"
checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c"
dependencies = [
"libc",
"log",
@ -412,7 +418,7 @@ version = "6.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6205bd8bb1e454ad2e27422015fb5e4f2bcc7e08fa8f27058670d208324a4d2d"
dependencies = [
"bitflags 2.4.1",
"bitflags 2.5.0",
"crossbeam-channel",
"filetime",
"fsevent-sys",
@ -438,9 +444,9 @@ dependencies = [
[[package]]
name = "num-traits"
version = "0.2.15"
version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a"
dependencies = [
"autocfg",
]
@ -453,20 +459,19 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
[[package]]
name = "portable-atomic"
version = "1.4.3"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "31114a898e107c51bb1609ffaf55a0e011cf6a4d7f1170d0015a165082c0338b"
checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0"
[[package]]
name = "predicates"
version = "3.0.3"
version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09963355b9f467184c04017ced4a2ba2d75cbcb4e7462690d388233253d4b1a9"
checksum = "68b87bfd4605926cdfefc1c3b5f8fe560e3feca9d5552cf68c466d3d8236c7e8"
dependencies = [
"anstyle",
"difflib",
"float-cmp",
"itertools",
"normalize-line-endings",
"predicates-core",
"regex",
@ -490,36 +495,48 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.53"
version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba466839c78239c09faf015484e5cc04860f88242cff4d03eb038f04b4699b73"
checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.26"
version = "1.0.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc"
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
dependencies = [
"proc-macro2",
]
[[package]]
name = "redox_syscall"
version = "0.3.5"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"
dependencies = [
"bitflags 1.3.2",
]
[[package]]
name = "regex"
version = "1.7.2"
version = "1.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cce168fea28d3e05f158bda4576cf0c844d5045bc2cc3620fa0292ed5bb5814c"
checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea"
dependencies = [
"aho-corasick",
"memchr",
@ -527,40 +544,49 @@ dependencies = [
]
[[package]]
name = "regex-automata"
version = "0.3.8"
name = "regex-syntax"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795"
checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56"
[[package]]
name = "regex-syntax"
version = "0.6.29"
name = "rustix"
version = "0.38.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89"
dependencies = [
"bitflags 2.5.0",
"errno",
"libc",
"linux-raw-sys",
"windows-sys 0.52.0",
]
[[package]]
name = "rustlings"
version = "5.6.1"
dependencies = [
"anyhow",
"assert_cmd",
"clap",
"console",
"glob",
"home",
"indicatif",
"notify-debouncer-mini",
"predicates",
"regex",
"serde",
"serde_json",
"toml",
"shlex",
"toml_edit",
"which",
"winnow",
]
[[package]]
name = "ryu"
version = "1.0.13"
version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041"
checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1"
[[package]]
name = "same-file"
@ -573,18 +599,18 @@ dependencies = [
[[package]]
name = "serde"
version = "1.0.158"
version = "1.0.197"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "771d4d9c4163ee138805e12c710dd365e4f44be8be0503cb1bb9eb989425d9c9"
checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.158"
version = "1.0.197"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e801c1712f48475582b7696ac71e0ca34ebb30e09338425384269d9717c62cad"
checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
dependencies = [
"proc-macro2",
"quote",
@ -593,9 +619,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.94"
version = "1.0.115"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c533a59c9d8a93a09c6ab31f0fd5e5f4dd1b8fc9434804029839884765d04ea"
checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd"
dependencies = [
"itoa",
"ryu",
@ -604,24 +630,30 @@ dependencies = [
[[package]]
name = "serde_spanned"
version = "0.6.3"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186"
checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1"
dependencies = [
"serde",
]
[[package]]
name = "strsim"
version = "0.10.0"
name = "shlex"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "strsim"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01"
[[package]]
name = "syn"
version = "2.0.8"
version = "2.0.55"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bcc02725fd69ab9f26eab07fad303e2497fad6fb9eba4f96c4d1687bdf704ad9"
checksum = "002a1b3dbf967edfafc32655d0f377ab0bb7b994aa1d32c8cc7e9b8bf3ebb8f0"
dependencies = [
"proc-macro2",
"quote",
@ -634,32 +666,20 @@ version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76"
[[package]]
name = "toml"
version = "0.7.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257"
dependencies = [
"serde",
"serde_spanned",
"toml_datetime",
"toml_edit",
]
[[package]]
name = "toml_datetime"
version = "0.6.3"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b"
checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1"
dependencies = [
"serde",
]
[[package]]
name = "toml_edit"
version = "0.19.15"
version = "0.22.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421"
checksum = "8e40bb779c5187258fd7aad0eb68cb8706a0a81fa712fbea808ab43c4b8374c4"
dependencies = [
"indexmap",
"serde",
@ -670,15 +690,15 @@ dependencies = [
[[package]]
name = "unicode-ident"
version = "1.0.8"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "unicode-width"
version = "0.1.10"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
[[package]]
name = "utf8parse"
@ -697,9 +717,9 @@ dependencies = [
[[package]]
name = "walkdir"
version = "2.3.3"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698"
checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
dependencies = [
"same-file",
"winapi-util",
@ -711,6 +731,18 @@ version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "which"
version = "6.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8211e4f58a2b2805adfbefbc07bab82958fc91e3836339b1ab7ae32465dce0d7"
dependencies = [
"either",
"home",
"rustix",
"winsafe",
]
[[package]]
name = "winapi"
version = "0.3.9"
@ -729,9 +761,9 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-util"
version = "0.1.5"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596"
dependencies = [
"winapi",
]
@ -742,28 +774,22 @@ 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 0.42.2",
"windows_aarch64_msvc 0.42.2",
"windows_i686_gnu 0.42.2",
"windows_i686_msvc 0.42.2",
"windows_x86_64_gnu 0.42.2",
"windows_x86_64_gnullvm 0.42.2",
"windows_x86_64_msvc 0.42.2",
]
[[package]]
name = "windows-sys"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
dependencies = [
"windows-targets",
"windows-targets 0.48.5",
]
[[package]]
name = "windows-sys"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
"windows-targets 0.52.4",
]
[[package]]
@ -782,10 +808,19 @@ dependencies = [
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.42.2"
name = "windows-targets"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b"
dependencies = [
"windows_aarch64_gnullvm 0.52.4",
"windows_aarch64_msvc 0.52.4",
"windows_i686_gnu 0.52.4",
"windows_i686_msvc 0.52.4",
"windows_x86_64_gnu 0.52.4",
"windows_x86_64_gnullvm 0.52.4",
"windows_x86_64_msvc 0.52.4",
]
[[package]]
name = "windows_aarch64_gnullvm"
@ -794,10 +829,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]]
name = "windows_aarch64_msvc"
version = "0.42.2"
name = "windows_aarch64_gnullvm"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9"
[[package]]
name = "windows_aarch64_msvc"
@ -806,10 +841,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]]
name = "windows_i686_gnu"
version = "0.42.2"
name = "windows_aarch64_msvc"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675"
[[package]]
name = "windows_i686_gnu"
@ -818,10 +853,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]]
name = "windows_i686_msvc"
version = "0.42.2"
name = "windows_i686_gnu"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3"
[[package]]
name = "windows_i686_msvc"
@ -830,10 +865,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]]
name = "windows_x86_64_gnu"
version = "0.42.2"
name = "windows_i686_msvc"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02"
[[package]]
name = "windows_x86_64_gnu"
@ -842,10 +877,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.42.2"
name = "windows_x86_64_gnu"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03"
[[package]]
name = "windows_x86_64_gnullvm"
@ -854,10 +889,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[package]]
name = "windows_x86_64_msvc"
version = "0.42.2"
name = "windows_x86_64_gnullvm"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177"
[[package]]
name = "windows_x86_64_msvc"
@ -866,10 +901,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
[[package]]
name = "winnow"
version = "0.5.15"
name = "windows_x86_64_msvc"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c2e3184b9c4e92ad5167ca73039d0c42476302ab603e2fec4487511f38ccefc"
checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8"
[[package]]
name = "winnow"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dffa400e67ed5a4dd237983829e66475f0a4a26938c4b04c21baede6262215b8"
dependencies = [
"memchr",
]
[[package]]
name = "winsafe"
version = "0.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904"

View File

@ -9,22 +9,23 @@ authors = [
edition = "2021"
[dependencies]
indicatif = "0.17.6"
console = "0.15"
anyhow = "1.0.81"
clap = { version = "4.5.4", features = ["derive"] }
console = "0.15.8"
indicatif = "0.17.8"
notify-debouncer-mini = "0.4.1"
toml = "0.7.6"
regex = "1.5"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0.81"
home = "0.5.3"
glob = "0.3.0"
clap = { version = "4.4.0", features = ["derive"] }
serde_json = "1.0.115"
serde = { version = "1.0.197", features = ["derive"] }
shlex = "1.3.0"
toml_edit = { version = "0.22.9", default-features = false, features = ["parse", "serde"] }
which = "6.0.1"
winnow = "0.6.5"
[[bin]]
name = "rustlings"
path = "src/main.rs"
[dev-dependencies]
assert_cmd = "2.0.12"
predicates = "3.0.3"
assert_cmd = "2.0.14"
glob = "0.3.0"
predicates = "3.1.0"

View File

@ -6,6 +6,7 @@
pub fn bigger(a: i32, b: i32) -> i32 {
// Complete this function to return the bigger number!
// If both numbers are equal, any of them can be returned.
// Do not use:
// - another function call
// - additional variables

View File

@ -11,7 +11,7 @@
fn main() {
let vec0 = vec![22, 44, 66];
let mut vec1 = fill_vec(vec0);
let vec1 = fill_vec(vec0);
assert_eq!(vec0, vec![22, 44, 66]);
assert_eq!(vec1, vec![22, 44, 66, 88]);

View File

@ -12,7 +12,7 @@
fn main() {
let vec0 = vec![22, 44, 66];
let mut vec1 = fill_vec(vec0);
let vec1 = fill_vec(vec0);
assert_eq!(vec1, vec![22, 44, 66, 88]);
}

View File

@ -13,7 +13,7 @@
fn main() {
let vec0 = vec![22, 44, 66];
let mut vec1 = fill_vec(vec0);
let vec1 = fill_vec(vec0);
assert_eq!(vec1, vec![22, 44, 66, 88]);
}

View File

@ -11,7 +11,7 @@ fn trim_me(input: &str) -> String {
}
fn compose_me(input: &str) -> String {
// TODO: Add " world!" to the string! There's multiple ways to do this!
// TODO: Add " world!" to the string! There are multiple ways to do this!
???
}

View File

@ -4,10 +4,11 @@
// 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.
// You have to build a scores table containing the name of the team, the total
// number of goals the team scored, and the total number of 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!
//

View File

@ -8,7 +8,7 @@
pub fn factorial(num: u64) -> u64 {
// Complete this function to return the factorial of num
// Do not use:
// - return
// - early returns (using the `return` keyword explicitly)
// Try not to use:
// - imperative style loops (for, while)
// - additional variables

View File

@ -27,22 +27,18 @@ impl Queue {
}
fn send_tx(q: Queue, tx: mpsc::Sender<u32>) -> () {
let qc = Arc::new(q);
let qc1 = Arc::clone(&qc);
let qc2 = Arc::clone(&qc);
thread::spawn(move || {
for val in &qc1.first_half {
for val in q.first_half {
println!("sending {:?}", val);
tx.send(*val).unwrap();
tx.send(val).unwrap();
thread::sleep(Duration::from_secs(1));
}
});
thread::spawn(move || {
for val in &qc2.second_half {
for val in q.second_half {
println!("sending {:?}", val);
tx.send(*val).unwrap();
tx.send(val).unwrap();
thread::sleep(Duration::from_secs(1));
}
});

View File

@ -24,8 +24,9 @@ impl Default for Person {
}
}
// Your task is to complete this implementation in order for the line `let p =
// Person::from("Mark,20")` to compile Please note that you'll need to parse the
// Your task is to complete this implementation in order for the line `let p1 =
// Person::from("Mark,20")` to compile. Please note that you'll need to parse the
// age component into a `usize` with something like `"4".parse::<usize>()`. The
// outcome of this needs to be handled appropriately.
//
@ -43,8 +44,7 @@ impl Default for Person {
// I AM NOT DONE
impl From<&str> for Person {
fn from(s: &str) -> Person {
}
fn from(s: &str) -> Person {}
}
fn main() {
@ -127,14 +127,14 @@ mod tests {
#[test]
fn test_trailing_comma() {
let p: Person = Person::from("Mike,32,");
assert_eq!(p.name, "Mike");
assert_eq!(p.age, 32);
assert_eq!(p.name, "John");
assert_eq!(p.age, 30);
}
#[test]
fn test_trailing_comma_and_some_string() {
let p: Person = Person::from("Mike,32,man");
assert_eq!(p.name, "Mike");
assert_eq!(p.age, 32);
let p: Person = Person::from("Mike,32,dog");
assert_eq!(p.name, "John");
assert_eq!(p.age, 30);
}
}

View File

@ -17,11 +17,11 @@
| error_handling | Β§9 |
| generics | Β§10 |
| traits | Β§10.2 |
| tests | Β§11.1 |
| lifetimes | Β§10.3 |
| tests | Β§11.1 |
| iterators | Β§13.2-4 |
| threads | Β§16.1-3 |
| smart_pointers | Β§15, Β§16.3 |
| threads | Β§16.1-3 |
| macros | Β§19.5 |
| clippy | Β§21.4 |
| conversions | n/a |

View File

@ -145,7 +145,7 @@ after the `->`. This is where the function's return type should be -- take a
look at the `is_even` function for an example!
Also: Did you figure out that, technically, `u32` would be the more fitting type
for the prices here, since they can't be negative? If so, kudos!"""
for the inputs of the functions here, since the original prices shouldn't be negative? If so, kudos!"""
[[exercises]]
name = "functions5"
@ -248,7 +248,7 @@ starting and ending (plus one) indices of the items in the `Array` that you
want to end up in the slice.
If you're curious why the first argument of `assert_eq!` does not have an
ampersand for a reference since the second argument is areference, take a look
ampersand for a reference since the second argument is a reference, take a look
at the coercion chapter of the nomicon:
https://doc.rust-lang.org/nomicon/coercions.html"""

View File

@ -137,7 +137,7 @@ fi
Path=${1:-rustlings/}
echo "Cloning Rustlings at $Path..."
git clone -q https://github.com/rust-lang/rustlings "$Path"
git clone -q https://github.com/rust-lang/rustlings.git "$Path"
cd "$Path"

View File

@ -1,19 +1,33 @@
use regex::Regex;
use serde::Deserialize;
use std::env;
use std::fmt::{self, Display, Formatter};
use std::fs::{self, remove_file, File};
use std::io::Read;
use std::io::{self, BufRead, BufReader};
use std::path::PathBuf;
use std::process::{self, Command};
use std::process::{self, exit, Command, Stdio};
use std::{array, env, mem};
use winnow::ascii::{space0, Caseless};
use winnow::combinator::opt;
use winnow::Parser;
const RUSTC_COLOR_ARGS: &[&str] = &["--color", "always"];
const RUSTC_EDITION_ARGS: &[&str] = &["--edition", "2021"];
const RUSTC_NO_DEBUG_ARGS: &[&str] = &["-C", "strip=debuginfo"];
const I_AM_DONE_REGEX: &str = r"(?m)^\s*///?\s*I\s+AM\s+NOT\s+DONE";
const CONTEXT: usize = 2;
const CLIPPY_CARGO_TOML_PATH: &str = "./exercises/22_clippy/Cargo.toml";
// Checks if the line contains the "I AM NOT DONE" comment.
fn contains_not_done_comment(input: &str) -> bool {
(
space0::<_, ()>,
"//",
opt('/'),
space0,
Caseless("I AM NOT DONE"),
)
.parse_next(&mut &*input)
.is_ok()
}
// Get a temporary file name that is hopefully unique
#[inline]
fn temp_file() -> String {
@ -58,7 +72,7 @@ pub struct Exercise {
// An enum to track of the state of an Exercise.
// An Exercise can be either Done or Pending
#[derive(PartialEq, Debug)]
#[derive(PartialEq, Eq, Debug)]
pub enum State {
// The state of the exercise once it's been completed
Done,
@ -67,7 +81,7 @@ pub enum State {
}
// The context information of a pending exercise
#[derive(PartialEq, Debug)]
#[derive(PartialEq, Eq, Debug)]
pub struct ContextLine {
// The source code that is still pending completion
pub line: String,
@ -148,7 +162,10 @@ path = "{}.rs""#,
.args(RUSTC_COLOR_ARGS)
.args(RUSTC_EDITION_ARGS)
.args(RUSTC_NO_DEBUG_ARGS)
.output()
.stdin(Stdio::null())
.stdout(Stdio::null())
.stderr(Stdio::null())
.status()
.expect("Failed to compile!");
// Due to an issue with Clippy, a cargo clean is required to catch all lints.
// See https://github.com/rust-lang/rust-clippy/issues/2604
@ -157,7 +174,10 @@ path = "{}.rs""#,
Command::new("cargo")
.args(["clean", "--manifest-path", CLIPPY_CARGO_TOML_PATH])
.args(RUSTC_COLOR_ARGS)
.output()
.stdin(Stdio::null())
.stdout(Stdio::null())
.stderr(Stdio::null())
.status()
.expect("Failed to run 'cargo clean'");
Command::new("cargo")
.args(["clippy", "--manifest-path", CLIPPY_CARGO_TOML_PATH])
@ -205,51 +225,101 @@ path = "{}.rs""#,
}
pub fn state(&self) -> State {
let mut source_file = File::open(&self.path).unwrap_or_else(|e| {
panic!(
"We were unable to open the exercise file {}! {e}",
self.path.display()
)
let source_file = File::open(&self.path).unwrap_or_else(|e| {
println!(
"Failed to open the exercise file {}: {e}",
self.path.display(),
);
exit(1);
});
let mut source_reader = BufReader::new(source_file);
let source = {
let mut s = String::new();
source_file.read_to_string(&mut s).unwrap_or_else(|e| {
panic!(
"We were unable to read the exercise file {}! {e}",
self.path.display()
)
});
s
// Read the next line into `buf` without the newline at the end.
let mut read_line = |buf: &mut String| -> io::Result<_> {
let n = source_reader.read_line(buf)?;
if buf.ends_with('\n') {
buf.pop();
if buf.ends_with('\r') {
buf.pop();
}
}
Ok(n)
};
let re = Regex::new(I_AM_DONE_REGEX).unwrap();
let mut current_line_number: usize = 1;
// Keep the last `CONTEXT` lines while iterating over the file lines.
let mut prev_lines: [_; CONTEXT] = array::from_fn(|_| String::with_capacity(256));
let mut line = String::with_capacity(256);
if !re.is_match(&source) {
return State::Done;
loop {
let n = read_line(&mut line).unwrap_or_else(|e| {
println!(
"Failed to read the exercise file {}: {e}",
self.path.display(),
);
exit(1);
});
// Reached the end of the file and didn't find the comment.
if n == 0 {
return State::Done;
}
if contains_not_done_comment(&line) {
let mut context = Vec::with_capacity(2 * CONTEXT + 1);
// Previous lines.
for (ind, prev_line) in prev_lines
.into_iter()
.take(current_line_number - 1)
.enumerate()
.rev()
{
context.push(ContextLine {
line: prev_line,
number: current_line_number - 1 - ind,
important: false,
});
}
// Current line.
context.push(ContextLine {
line,
number: current_line_number,
important: true,
});
// Next lines.
for ind in 0..CONTEXT {
let mut next_line = String::with_capacity(256);
let Ok(n) = read_line(&mut next_line) else {
// If an error occurs, just ignore the next lines.
break;
};
// Reached the end of the file.
if n == 0 {
break;
}
context.push(ContextLine {
line: next_line,
number: current_line_number + 1 + ind,
important: false,
});
}
return State::Pending(context);
}
current_line_number += 1;
// Add the current line as a previous line and shift the older lines by one.
for prev_line in &mut prev_lines {
mem::swap(&mut line, prev_line);
}
// The current line now contains the oldest previous line.
// Recycle it for reading the next line.
line.clear();
}
let matched_line_index = source
.lines()
.enumerate()
.find_map(|(i, line)| if re.is_match(line) { Some(i) } else { None })
.expect("This should not happen at all");
let min_line = ((matched_line_index as i32) - (CONTEXT as i32)).max(0) as usize;
let max_line = matched_line_index + CONTEXT;
let context = source
.lines()
.enumerate()
.filter(|&(i, _)| i >= min_line && i <= max_line)
.map(|(i, line)| ContextLine {
line: line.to_string(),
number: i + 1,
important: i == matched_line_index,
})
.collect();
State::Pending(context)
}
// Check that the exercise looks to be solved using self.state()
@ -375,4 +445,20 @@ mod test {
let out = exercise.compile().unwrap().run().unwrap();
assert!(out.stdout.contains("THIS TEST TOO SHALL PASS"));
}
#[test]
fn test_not_done() {
assert!(contains_not_done_comment("// I AM NOT DONE"));
assert!(contains_not_done_comment("/// I AM NOT DONE"));
assert!(contains_not_done_comment("// I AM NOT DONE"));
assert!(contains_not_done_comment("/// I AM NOT DONE"));
assert!(contains_not_done_comment("// I AM NOT DONE "));
assert!(contains_not_done_comment("// I AM NOT DONE!"));
assert!(contains_not_done_comment("// I am not done"));
assert!(contains_not_done_comment("// i am NOT done"));
assert!(!contains_not_done_comment("I AM NOT DONE"));
assert!(!contains_not_done_comment("// NOT DONE"));
assert!(!contains_not_done_comment("DONE"));
}
}

View File

@ -1,16 +1,18 @@
use crate::exercise::{Exercise, ExerciseList};
use crate::project::RustAnalyzerProject;
use crate::project::write_project_json;
use crate::run::{reset, run};
use crate::verify::verify;
use anyhow::Result;
use clap::{Parser, Subcommand};
use console::Emoji;
use notify_debouncer_mini::notify::{self, RecursiveMode};
use notify_debouncer_mini::{new_debouncer, DebouncedEventKind};
use shlex::Shlex;
use std::ffi::OsStr;
use std::fs;
use std::io::{self, prelude::*};
use std::path::Path;
use std::process::{Command, Stdio};
use std::process::Command;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::mpsc::{channel, RecvTimeoutError};
use std::sync::{Arc, Mutex};
@ -84,31 +86,32 @@ enum Subcommands {
Lsp,
}
fn main() {
fn main() -> Result<()> {
let args = Args::parse();
if args.command.is_none() {
println!("\n{WELCOME}\n");
}
if !Path::new("info.toml").exists() {
println!(
"{} must be run from the rustlings directory",
std::env::current_exe().unwrap().to_str().unwrap()
);
println!("Try `cd rustlings/`!");
std::process::exit(1);
}
if !rustc_exists() {
if which::which("rustc").is_err() {
println!("We cannot find `rustc`.");
println!("Try running `rustc --version` to diagnose your problem.");
println!("For instructions on how to install Rust, check the README.");
std::process::exit(1);
}
let toml_str = &fs::read_to_string("info.toml").unwrap();
let exercises = toml::from_str::<ExerciseList>(toml_str).unwrap().exercises;
let info_file = fs::read_to_string("info.toml").unwrap_or_else(|e| {
match e.kind() {
io::ErrorKind::NotFound => println!(
"The program must be run from the rustlings directory\nTry `cd rustlings/`!",
),
_ => println!("Failed to read the info.toml file: {e}"),
}
std::process::exit(1);
});
let exercises = toml_edit::de::from_str::<ExerciseList>(&info_file)
.unwrap()
.exercises;
let verbose = args.nocapture;
let command = args.command.unwrap_or_else(|| {
@ -128,31 +131,43 @@ fn main() {
println!("{:<17}\t{:<46}\t{:<7}", "Name", "Path", "Status");
}
let mut exercises_done: u16 = 0;
let filters = filter.clone().unwrap_or_default().to_lowercase();
exercises.iter().for_each(|e| {
let fname = format!("{}", e.path.display());
let lowercase_filter = filter
.as_ref()
.map(|s| s.to_lowercase())
.unwrap_or_default();
let filters = lowercase_filter
.split(',')
.filter_map(|f| {
let f = f.trim();
if f.is_empty() {
None
} else {
Some(f)
}
})
.collect::<Vec<_>>();
for exercise in &exercises {
let fname = exercise.path.to_string_lossy();
let filter_cond = filters
.split(',')
.filter(|f| !f.trim().is_empty())
.any(|f| e.name.contains(f) || fname.contains(f));
let status = if e.looks_done() {
.iter()
.any(|f| exercise.name.contains(f) || fname.contains(f));
let looks_done = exercise.looks_done();
let status = if looks_done {
exercises_done += 1;
"Done"
} else {
"Pending"
};
let solve_cond = {
(e.looks_done() && solved)
|| (!e.looks_done() && unsolved)
|| (!solved && !unsolved)
};
let solve_cond =
(looks_done && solved) || (!looks_done && unsolved) || (!solved && !unsolved);
if solve_cond && (filter_cond || filter.is_none()) {
let line = if paths {
format!("{fname}\n")
} else if names {
format!("{}\n", e.name)
format!("{}\n", exercise.name)
} else {
format!("{:<17}\t{fname:<46}\t{status:<7}\n", e.name)
format!("{:<17}\t{fname:<46}\t{status:<7}\n", exercise.name)
};
// Somehow using println! leads to the binary panicking
// when its output is piped.
@ -168,7 +183,8 @@ fn main() {
});
}
}
});
}
let percentage_progress = exercises_done as f32 / exercises.len() as f32 * 100.0;
println!(
"Progress: You completed {} / {} exercises ({:.1} %).",
@ -203,30 +219,17 @@ fn main() {
}
Subcommands::Lsp => {
let mut project = RustAnalyzerProject::new();
project
.get_sysroot_src()
.expect("Couldn't find toolchain path, do you have `rustc` installed?");
project
.exercises_to_json()
.expect("Couldn't parse rustlings exercises files");
if project.crates.is_empty() {
println!("Failed find any exercises, make sure you're in the `rustlings` folder");
} else if project.write_to_disk().is_err() {
println!("Failed to write rust-project.json to disk for rust-analyzer");
if let Err(e) = write_project_json(exercises) {
println!("Failed to write rust-project.json to disk for rust-analyzer: {e}");
} else {
println!("Successfully generated rust-project.json");
println!("rust-analyzer will now parse exercises, restart your language server or editor")
println!("rust-analyzer will now parse exercises, restart your language server or editor");
}
}
Subcommands::Watch { success_hints } => match watch(&exercises, verbose, success_hints) {
Err(e) => {
println!(
"Error: Could not watch your progress. Error message was {:?}.",
e
);
println!("Error: Could not watch your progress. Error message was {e:?}.");
println!("Most likely you've run out of disk space or your 'inotify limit' has been reached.");
std::process::exit(1);
}
@ -243,56 +246,60 @@ fn main() {
}
},
}
Ok(())
}
fn spawn_watch_shell(
failed_exercise_hint: &Arc<Mutex<Option<String>>>,
failed_exercise_hint: Arc<Mutex<Option<String>>>,
should_quit: Arc<AtomicBool>,
) {
let failed_exercise_hint = Arc::clone(failed_exercise_hint);
println!("Welcome to watch mode! You can type 'help' to get an overview of the commands you can use here.");
thread::spawn(move || loop {
let mut input = String::new();
match io::stdin().read_line(&mut input) {
Ok(_) => {
let input = input.trim();
if input == "hint" {
if let Some(hint) = &*failed_exercise_hint.lock().unwrap() {
println!("{hint}");
}
} else if input == "clear" {
println!("\x1B[2J\x1B[1;1H");
} else if input.eq("quit") {
should_quit.store(true, Ordering::SeqCst);
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!(" !<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}");
}
thread::spawn(move || {
let mut input = String::with_capacity(32);
let mut stdin = io::stdin().lock();
loop {
// Recycle input buffer.
input.clear();
if let Err(e) = stdin.read_line(&mut input) {
println!("error reading command: {e}");
}
let input = input.trim();
if input == "hint" {
if let Some(hint) = &*failed_exercise_hint.lock().unwrap() {
println!("{hint}");
}
} else if input == "clear" {
println!("\x1B[2J\x1B[1;1H");
} else if input == "quit" {
should_quit.store(true, Ordering::SeqCst);
println!("Bye!");
} else if input == "help" {
println!("{WATCH_MODE_HELP_MESSAGE}");
} else if let Some(cmd) = input.strip_prefix('!') {
let mut parts = Shlex::new(cmd);
let Some(program) = parts.next() else {
println!("no command provided");
continue;
};
if let Err(e) = Command::new(program).args(parts).status() {
println!("failed to execute command `{cmd}`: {e}");
}
} else {
println!("unknown command: {input}\n{WATCH_MODE_HELP_MESSAGE}");
}
Err(error) => println!("error reading command: {error}"),
}
});
}
fn find_exercise<'a>(name: &str, exercises: &'a [Exercise]) -> &'a Exercise {
if name.eq("next") {
if name == "next" {
exercises
.iter()
.find(|e| !e.looks_done())
@ -338,7 +345,6 @@ fn watch(
clear_screen();
let to_owned_hint = |t: &Exercise| t.hint.to_owned();
let failed_exercise_hint = match verify(
exercises.iter(),
(0, exercises.len()),
@ -346,9 +352,9 @@ fn watch(
success_hints,
) {
Ok(_) => return Ok(WatchStatus::Finished),
Err(exercise) => Arc::new(Mutex::new(Some(to_owned_hint(exercise)))),
Err(exercise) => Arc::new(Mutex::new(Some(exercise.hint.clone()))),
};
spawn_watch_shell(&failed_exercise_hint, Arc::clone(&should_quit));
spawn_watch_shell(Arc::clone(&failed_exercise_hint), Arc::clone(&should_quit));
loop {
match rx.recv_timeout(Duration::from_secs(1)) {
Ok(event) => match event {
@ -383,7 +389,7 @@ fn watch(
Err(exercise) => {
let mut failed_exercise_hint =
failed_exercise_hint.lock().unwrap();
*failed_exercise_hint = Some(to_owned_hint(exercise));
*failed_exercise_hint = Some(exercise.hint.clone());
}
}
}
@ -403,19 +409,7 @@ fn watch(
}
}
fn rustc_exists() -> bool {
Command::new("rustc")
.args(["--version"])
.stdout(Stdio::null())
.stderr(Stdio::null())
.stdin(Stdio::null())
.spawn()
.and_then(|mut child| child.wait())
.map(|status| status.success())
.unwrap_or(false)
}
const DEFAULT_OUT: &str = r#"Thanks for installing Rustlings!
const DEFAULT_OUT: &str = "Thanks for installing Rustlings!
Is this your first time? Don't worry, Rustlings was made for beginners! We are
going to teach you a lot of things about Rust, but before we can get
@ -441,7 +435,7 @@ started, here's a couple of notes about how Rustlings operates:
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!"#;
exercise. Make sure to have your editor open!";
const FENISH_LINE: &str = "+----------------------------------------------------+
| You made it to the Fe-nish line! |
@ -477,3 +471,13 @@ const WELCOME: &str = r" welcome to...
| | | |_| \__ \ |_| | | | | | (_| \__ \
|_| \__,_|___/\__|_|_|_| |_|\__, |___/
|___/";
const WATCH_MODE_HELP_MESSAGE: &str = "Commands available to you in watch mode:
hint - prints the current exercise's hint
clear - clears the screen
quit - quits watch mode
!<cmd> - executes a command, like `!rustc --explain E0381`
help - displays this help message
Watch mode automatically re-evaluates the current exercise
when you edit a file's contents.";

View File

@ -1,99 +1,83 @@
use glob::glob;
use serde::{Deserialize, Serialize};
use anyhow::{Context, Result};
use serde::Serialize;
use std::env;
use std::error::Error;
use std::path::PathBuf;
use std::process::Command;
use std::process::{Command, Stdio};
use crate::exercise::Exercise;
/// Contains the structure of resulting rust-project.json file
/// and functions to build the data required to create the file
#[derive(Serialize, Deserialize)]
pub struct RustAnalyzerProject {
sysroot_src: String,
pub crates: Vec<Crate>,
#[derive(Serialize)]
struct RustAnalyzerProject {
sysroot_src: PathBuf,
crates: Vec<Crate>,
}
#[derive(Serialize, Deserialize)]
pub struct Crate {
root_module: String,
edition: String,
deps: Vec<String>,
cfg: Vec<String>,
#[derive(Serialize)]
struct Crate {
root_module: PathBuf,
edition: &'static str,
// Not used, but required in the JSON file.
deps: Vec<()>,
// Only `test` is used for all crates.
// Therefore, an array is used instead of a `Vec`.
cfg: [&'static str; 1],
}
impl RustAnalyzerProject {
pub fn new() -> RustAnalyzerProject {
RustAnalyzerProject {
sysroot_src: String::new(),
crates: Vec::new(),
}
}
fn build(exercises: Vec<Exercise>) -> Result<Self> {
let crates = exercises
.into_iter()
.map(|exercise| Crate {
root_module: exercise.path,
edition: "2021",
deps: Vec::new(),
// This allows rust_analyzer to work inside `#[test]` blocks
cfg: ["test"],
})
.collect();
/// Write rust-project.json to disk
pub fn write_to_disk(&self) -> Result<(), std::io::Error> {
std::fs::write(
"./rust-project.json",
serde_json::to_vec(&self).expect("Failed to serialize to JSON"),
)?;
Ok(())
}
/// If path contains .rs extension, add a crate to `rust-project.json`
fn path_to_json(&mut self, path: PathBuf) -> Result<(), Box<dyn Error>> {
if let Some(ext) = path.extension() {
if ext == "rs" {
self.crates.push(Crate {
root_module: path.display().to_string(),
edition: "2021".to_string(),
deps: Vec::new(),
// This allows rust_analyzer to work inside #[test] blocks
cfg: vec!["test".to_string()],
})
}
}
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 path in glob("./exercises/**/*")? {
self.path_to_json(path?)?;
}
Ok(())
}
/// Use `rustc` to determine the default toolchain
pub fn get_sysroot_src(&mut self) -> Result<(), Box<dyn Error>> {
// check if RUST_SRC_PATH is set
if let Ok(path) = env::var("RUST_SRC_PATH") {
self.sysroot_src = path;
return Ok(());
if let Some(path) = env::var_os("RUST_SRC_PATH") {
return Ok(Self {
sysroot_src: PathBuf::from(path),
crates,
});
}
let toolchain = Command::new("rustc")
.arg("--print")
.arg("sysroot")
.output()?
.stderr(Stdio::inherit())
.output()
.context("Failed to get the sysroot from `rustc`. Do you have `rustc` installed?")?
.stdout;
let toolchain = String::from_utf8_lossy(&toolchain);
let mut whitespace_iter = toolchain.split_whitespace();
let toolchain =
String::from_utf8(toolchain).context("The toolchain path is invalid UTF8")?;
let toolchain = toolchain.trim_end();
println!("Determined toolchain: {toolchain}\n");
let toolchain = whitespace_iter.next().unwrap_or(&toolchain);
let mut sysroot_src = PathBuf::with_capacity(256);
sysroot_src.extend([toolchain, "lib", "rustlib", "src", "rust", "library"]);
println!("Determined toolchain: {}\n", &toolchain);
self.sysroot_src = (std::path::Path::new(toolchain)
.join("lib")
.join("rustlib")
.join("src")
.join("rust")
.join("library")
.to_string_lossy())
.to_string();
Ok(())
Ok(Self {
sysroot_src,
crates,
})
}
}
/// Write `rust-project.json` to disk.
pub fn write_project_json(exercises: Vec<Exercise>) -> Result<()> {
let content = RustAnalyzerProject::build(exercises)?;
// Using the capacity 2^14 since the file length in bytes is higher than 2^13.
// The final length is not known exactly because it depends on the user's sysroot path,
// the current number of exercises etc.
let mut buf = Vec::with_capacity(1 << 14);
serde_json::to_writer(&mut buf, &content)?;
std::fs::write("rust-project.json", buf)?;
Ok(())
}

View File

@ -21,7 +21,8 @@ pub fn run(exercise: &Exercise, verbose: bool) -> Result<(), ()> {
// Resets the exercise by stashing the changes.
pub fn reset(exercise: &Exercise) -> Result<(), ()> {
let command = Command::new("git")
.args(["stash", "--"])
.arg("stash")
.arg("--")
.arg(&exercise.path)
.spawn();

View File

@ -1,33 +1,28 @@
macro_rules! warn {
($fmt:literal, $ex:expr) => {{
macro_rules! print_emoji {
($emoji:expr, $sign:expr, $color: ident, $fmt:literal, $ex:expr) => {{
use console::{style, Emoji};
use std::env;
let formatstr = format!($fmt, $ex);
if env::var("NO_EMOJI").is_ok() {
println!("{} {}", style("!").red(), style(formatstr).red());
println!("{} {}", style($sign).$color(), style(formatstr).$color());
} else {
println!(
"{} {}",
style(Emoji("⚠️ ", "!")).red(),
style(formatstr).red()
style(Emoji($emoji, $sign)).$color(),
style(formatstr).$color()
);
}
}};
}
macro_rules! success {
macro_rules! warn {
($fmt:literal, $ex:expr) => {{
use console::{style, Emoji};
use std::env;
let formatstr = format!($fmt, $ex);
if env::var("NO_EMOJI").is_ok() {
println!("{} {}", style("βœ“").green(), style(formatstr).green());
} else {
println!(
"{} {}",
style(Emoji("βœ…", "βœ“")).green(),
style(formatstr).green()
);
}
print_emoji!("⚠️ ", "!", red, $fmt, $ex);
}};
}
macro_rules! success {
($fmt:literal, $ex:expr) => {{
print_emoji!("βœ… ", "βœ“", green, $fmt, $ex);
}};
}

View File

@ -24,7 +24,7 @@ pub fn verify<'a>(
.progress_chars("#>-"),
);
bar.set_position(num_done as u64);
bar.set_message(format!("({:.1} %)", percentage));
bar.set_message(format!("({percentage:.1} %)"));
for exercise in exercises {
let compile_result = match exercise.mode {
@ -37,11 +37,21 @@ pub fn verify<'a>(
}
percentage += 100.0 / total as f32;
bar.inc(1);
bar.set_message(format!("({:.1} %)", percentage));
bar.set_message(format!("({percentage:.1} %)"));
if bar.position() == total as u64 {
println!(
"Progress: You completed {} / {} exercises ({:.1} %).",
bar.position(),
total,
percentage
);
bar.finish();
}
}
Ok(())
}
#[derive(PartialEq, Eq)]
enum RunMode {
Interactive,
NonInteractive,
@ -115,7 +125,7 @@ fn compile_and_test(
if verbose {
println!("{}", output.stdout);
}
if let RunMode::Interactive = run_mode {
if run_mode == RunMode::Interactive {
Ok(prompt_for_completion(exercise, None, success_hints))
} else {
Ok(true)
@ -182,27 +192,25 @@ fn prompt_for_completion(
Mode::Test => "The code is compiling, and the tests pass!",
Mode::Clippy => clippy_success_msg,
};
println!();
if no_emoji {
println!("~*~ {success_msg} ~*~")
println!("\n~*~ {success_msg} ~*~\n");
} else {
println!("πŸŽ‰ πŸŽ‰ {success_msg} πŸŽ‰ πŸŽ‰")
println!("\nπŸŽ‰ πŸŽ‰ {success_msg} πŸŽ‰ πŸŽ‰\n");
}
println!();
if let Some(output) = prompt_output {
println!("Output:");
println!("{}", separator());
println!("{output}");
println!("{}", separator());
println!();
println!(
"Output:\n{separator}\n{output}\n{separator}\n",
separator = separator(),
);
}
if success_hints {
println!("Hints:");
println!("{}", separator());
println!("{}", exercise.hint);
println!("{}", separator());
println!();
println!(
"Hints:\n{separator}\n{}\n{separator}\n",
exercise.hint,
separator = separator(),
);
}
println!("You can keep working on this exercise,");
@ -215,14 +223,14 @@ fn prompt_for_completion(
let formatted_line = if context_line.important {
format!("{}", style(context_line.line).bold())
} else {
context_line.line.to_string()
context_line.line
};
println!(
"{:>2} {} {}",
style(context_line.number).blue().bold(),
style("|").blue(),
formatted_line
formatted_line,
);
}