fixed conflict

This commit is contained in:
Steff 2022-08-23 23:02:46 +03:00
commit f01b67f915
22 changed files with 668 additions and 139 deletions

View File

@ -1371,6 +1371,159 @@
"contributions": [ "contributions": [
"content" "content"
] ]
},
{
"login": "wojexe",
"name": "wojexe",
"avatar_url": "https://avatars.githubusercontent.com/u/21208490?v=4",
"profile": "https://wojexe.com",
"contributions": [
"content"
]
},
{
"login": "Tostapunk",
"name": "Mattia Schiavon",
"avatar_url": "https://avatars.githubusercontent.com/u/25140297?v=4",
"profile": "https://github.com/Tostapunk",
"contributions": [
"content"
]
},
{
"login": "PrettyWood",
"name": "Eric Jolibois",
"avatar_url": "https://avatars.githubusercontent.com/u/18406791?v=4",
"profile": "http://toucantoco.com",
"contributions": [
"content"
]
},
{
"login": "EdwinChang24",
"name": "Edwin Chang",
"avatar_url": "https://avatars.githubusercontent.com/u/88263098?v=4",
"profile": "http://edwinchang.vercel.app",
"contributions": [
"content"
]
},
{
"login": "saikatdas0790",
"name": "Saikat Das",
"avatar_url": "https://avatars.githubusercontent.com/u/7412443?v=4",
"profile": "https://saikat.dev/",
"contributions": [
"content"
]
},
{
"login": "thatlittleboy",
"name": "Jeremy Goh",
"avatar_url": "https://avatars.githubusercontent.com/u/30731072?v=4",
"profile": "https://github.com/thatlittleboy",
"contributions": [
"content"
]
},
{
"login": "Lioness100",
"name": "Lioness100",
"avatar_url": "https://avatars.githubusercontent.com/u/65814829?v=4",
"profile": "https://github.com/Lioness100",
"contributions": [
"content"
]
},
{
"login": "tvkn",
"name": "Tristan Nicholls",
"avatar_url": "https://avatars.githubusercontent.com/u/79277926?v=4",
"profile": "https://github.com/tvkn",
"contributions": [
"content"
]
},
{
"login": "clairew",
"name": "Claire",
"avatar_url": "https://avatars.githubusercontent.com/u/9344258?v=4",
"profile": "http://clairewang.net",
"contributions": [
"content"
]
},
{
"login": "Mouwrice",
"name": "Maurice Van Wassenhove",
"avatar_url": "https://avatars.githubusercontent.com/u/56763273?v=4",
"profile": "https://github.com/Mouwrice",
"contributions": [
"content"
]
},
{
"login": "johnmendel",
"name": "John Mendelewski",
"avatar_url": "https://avatars.githubusercontent.com/u/77524?v=4",
"profile": "http://jmthree.com",
"contributions": [
"code"
]
},
{
"login": "brianfakhoury",
"name": "Brian Fakhoury",
"avatar_url": "https://avatars.githubusercontent.com/u/20828724?v=4",
"profile": "http://fakhoury.xyz",
"contributions": [
"content"
]
},
{
"login": "markusboehme",
"name": "Markus Boehme",
"avatar_url": "https://avatars.githubusercontent.com/u/5074759?v=4",
"profile": "https://github.com/markusboehme",
"contributions": [
"code"
]
},
{
"login": "nico-vromans",
"name": "Nico Vromans",
"avatar_url": "https://avatars.githubusercontent.com/u/48183857?v=4",
"profile": "https://github.com/nico-vromans",
"contributions": [
"content"
]
},
{
"login": "vostok92",
"name": "vostok92",
"avatar_url": "https://avatars.githubusercontent.com/u/540339?v=4",
"profile": "https://github.com/vostok92",
"contributions": [
"content"
]
},
{
"login": "magnusrodseth",
"name": "Magnus Rødseth",
"avatar_url": "https://avatars.githubusercontent.com/u/59113973?v=4",
"profile": "http://magnusrodseth.vercel.app",
"contributions": [
"content"
]
},
{
"login": "rubiesonthesky",
"name": "rubiesonthesky",
"avatar_url": "https://avatars.githubusercontent.com/u/2591240?v=4",
"profile": "https://github.com/rubiesonthesky",
"contributions": [
"content"
]
} }
], ],
"contributorsPerLine": 8, "contributorsPerLine": 8,

View File

@ -2,6 +2,6 @@ root = true
[*.rs] [*.rs]
end_of_line = lf end_of_line = lf
insert_final_newfile = true insert_final_newline = true
indent_style = space indent_style = space
indent_size = 4 indent_size = 4

View File

@ -195,6 +195,27 @@ authors.
<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://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/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> <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>
<td align="center"><a href="https://wojexe.com"><img src="https://avatars.githubusercontent.com/u/21208490?v=4?s=100" width="100px;" alt=""/><br /><sub><b>wojexe</b></sub></a><br /><a href="#content-wojexe" title="Content">🖋</a></td>
<td align="center"><a href="https://github.com/Tostapunk"><img src="https://avatars.githubusercontent.com/u/25140297?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Mattia Schiavon</b></sub></a><br /><a href="#content-Tostapunk" title="Content">🖋</a></td>
<td align="center"><a href="http://toucantoco.com"><img src="https://avatars.githubusercontent.com/u/18406791?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Eric Jolibois</b></sub></a><br /><a href="#content-PrettyWood" title="Content">🖋</a></td>
</tr>
<tr>
<td align="center"><a href="http://edwinchang.vercel.app"><img src="https://avatars.githubusercontent.com/u/88263098?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Edwin Chang</b></sub></a><br /><a href="#content-EdwinChang24" title="Content">🖋</a></td>
<td align="center"><a href="https://saikat.dev/"><img src="https://avatars.githubusercontent.com/u/7412443?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Saikat Das</b></sub></a><br /><a href="#content-saikatdas0790" title="Content">🖋</a></td>
<td align="center"><a href="https://github.com/thatlittleboy"><img src="https://avatars.githubusercontent.com/u/30731072?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jeremy Goh</b></sub></a><br /><a href="#content-thatlittleboy" title="Content">🖋</a></td>
<td align="center"><a href="https://github.com/Lioness100"><img src="https://avatars.githubusercontent.com/u/65814829?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Lioness100</b></sub></a><br /><a href="#content-Lioness100" title="Content">🖋</a></td>
<td align="center"><a href="https://github.com/tvkn"><img src="https://avatars.githubusercontent.com/u/79277926?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Tristan Nicholls</b></sub></a><br /><a href="#content-tvkn" title="Content">🖋</a></td>
<td align="center"><a href="http://clairewang.net"><img src="https://avatars.githubusercontent.com/u/9344258?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Claire</b></sub></a><br /><a href="#content-clairew" title="Content">🖋</a></td>
<td align="center"><a href="https://github.com/Mouwrice"><img src="https://avatars.githubusercontent.com/u/56763273?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Maurice Van Wassenhove</b></sub></a><br /><a href="#content-Mouwrice" title="Content">🖋</a></td>
<td align="center"><a href="http://jmthree.com"><img src="https://avatars.githubusercontent.com/u/77524?v=4?s=100" width="100px;" alt=""/><br /><sub><b>John Mendelewski</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=johnmendel" title="Code">💻</a></td>
</tr>
<tr>
<td align="center"><a href="http://fakhoury.xyz"><img src="https://avatars.githubusercontent.com/u/20828724?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Brian Fakhoury</b></sub></a><br /><a href="#content-brianfakhoury" title="Content">🖋</a></td>
<td align="center"><a href="https://github.com/markusboehme"><img src="https://avatars.githubusercontent.com/u/5074759?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Markus Boehme</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=markusboehme" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/nico-vromans"><img src="https://avatars.githubusercontent.com/u/48183857?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Nico Vromans</b></sub></a><br /><a href="#content-nico-vromans" title="Content">🖋</a></td>
<td align="center"><a href="https://github.com/vostok92"><img src="https://avatars.githubusercontent.com/u/540339?v=4?s=100" width="100px;" alt=""/><br /><sub><b>vostok92</b></sub></a><br /><a href="#content-vostok92" title="Content">🖋</a></td>
<td align="center"><a href="http://magnusrodseth.vercel.app"><img src="https://avatars.githubusercontent.com/u/59113973?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Magnus Rødseth</b></sub></a><br /><a href="#content-magnusrodseth" title="Content">🖋</a></td>
<td align="center"><a href="https://github.com/rubiesonthesky"><img src="https://avatars.githubusercontent.com/u/2591240?v=4?s=100" width="100px;" alt=""/><br /><sub><b>rubiesonthesky</b></sub></a><br /><a href="#content-rubiesonthesky" title="Content">🖋</a></td>
</tr> </tr>
</table> </table>

View File

@ -1,3 +1,45 @@
<a name="5.1.1"></a>
## 5.1.1 (2022-08-17)
#### Bug Fixes
- Fixed an incorrect assertion in options1
<a name="5.1.0"></a>
## 5.1.0 (2022-08-16)
#### Features
- Added a new `rc1` exercise.
- Added a new `cow1` exercise.
#### Bug Fixes
- **variables5**: Corrected reference to previous exercise
- **functions4**: Fixed line number reference
- **strings3**: Clarified comment wording
- **traits4, traits5**: Fixed line number reference
- **traits5**:
- Fixed typo in "parameter"
- Made exercise prefer a traits-based solution
- **lifetimes2**: Improved hint
- **threads3**: Fixed typo in hint
- **box1**: Replaced `unimplemented!` with `todo!`
- **errors5**: Provided an explanation for usage of `Box<dyn Error>`
- **quiz2**: Fixed a typo
- **macros**: Updated the macros book link
- **options1**:
- Removed unused code
- Added more granular tests
- Fixed some comment syntax shenanigans in info.toml
#### Housekeeping
- Fixed a typo in .editorconfig
- Fixed a typo in integration_tests.rs
- Clarified manual installation instructions using `cargo install --path .`
- Added a link to our Zulip in the readme file
<a name="5.0.0"></a> <a name="5.0.0"></a>
## 5.0.0 (2022-07-16) ## 5.0.0 (2022-07-16)

183
Cargo.lock generated
View File

@ -13,9 +13,9 @@ dependencies = [
[[package]] [[package]]
name = "argh" name = "argh"
version = "0.1.5" version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e7317a549bc17c5278d9e72bb6e62c6aa801ac2567048e39ebc1c194249323e" checksum = "a7e7e4aa7e40747e023c0761dafcb42333a9517575bbf1241747f68dd3177a62"
dependencies = [ dependencies = [
"argh_derive", "argh_derive",
"argh_shared", "argh_shared",
@ -23,9 +23,9 @@ dependencies = [
[[package]] [[package]]
name = "argh_derive" name = "argh_derive"
version = "0.1.5" version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60949c42375351e9442e354434b0cba2ac402c1237edf673cac3a4bf983b8d3c" checksum = "69f2bd7ff6ed6414f4e5521bd509bae46454bbd513801767ced3f21a751ab4bc"
dependencies = [ dependencies = [
"argh_shared", "argh_shared",
"heck", "heck",
@ -36,9 +36,9 @@ dependencies = [
[[package]] [[package]]
name = "argh_shared" name = "argh_shared"
version = "0.1.5" version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a61eb019cb8f415d162cb9f12130ee6bbe9168b7d953c17f4ad049e4051ca00" checksum = "47253b98986dafc7a3e1cf3259194f1f47ac61abb57a57f46ec09e48d004ecda"
[[package]] [[package]]
name = "assert_cmd" name = "assert_cmd"
@ -54,9 +54,9 @@ dependencies = [
[[package]] [[package]]
name = "autocfg" name = "autocfg"
version = "1.0.1" version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]] [[package]]
name = "bitflags" name = "bitflags"
@ -78,14 +78,13 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]] [[package]]
name = "console" name = "console"
version = "0.15.0" version = "0.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a28b32d32ca44b70c3e4acd7db1babf555fa026e385fb95f18028f88848b3c31" checksum = "89eab4d20ce20cea182308bca13088fecea9c05f6776cf287205d41a0ed3c847"
dependencies = [ dependencies = [
"encode_unicode", "encode_unicode",
"libc", "libc",
"once_cell", "once_cell",
"regex",
"terminal_size", "terminal_size",
"unicode-width", "unicode-width",
"winapi 0.3.9", "winapi 0.3.9",
@ -117,14 +116,14 @@ dependencies = [
[[package]] [[package]]
name = "filetime" name = "filetime"
version = "0.2.15" version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "975ccf83d8d9d0d84682850a38c8169027be83368805971cc4f238c2b245bc98" checksum = "e94a7bbaa59354bc20dd75b67f23e2797b4490e9d6928203fb105c79e448c86c"
dependencies = [ dependencies = [
"cfg-if 1.0.0", "cfg-if 1.0.0",
"libc", "libc",
"redox_syscall", "redox_syscall",
"winapi 0.3.9", "windows-sys",
] ]
[[package]] [[package]]
@ -238,9 +237,9 @@ dependencies = [
[[package]] [[package]]
name = "itoa" name = "itoa"
version = "1.0.2" version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754"
[[package]] [[package]]
name = "kernel32-sys" name = "kernel32-sys"
@ -266,24 +265,24 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.100" version = "0.2.132"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1fa8cddc8fbbee11227ef194b5317ed014b8acbf15139bd716a18ad3fe99ec5" checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5"
[[package]] [[package]]
name = "log" name = "log"
version = "0.4.14" version = "0.4.17"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
dependencies = [ dependencies = [
"cfg-if 1.0.0", "cfg-if 1.0.0",
] ]
[[package]] [[package]]
name = "memchr" name = "memchr"
version = "2.4.1" version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]] [[package]]
name = "mio" name = "mio"
@ -365,9 +364,9 @@ dependencies = [
[[package]] [[package]]
name = "num-traits" name = "num-traits"
version = "0.2.14" version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
dependencies = [ dependencies = [
"autocfg", "autocfg",
] ]
@ -380,9 +379,9 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
[[package]] [[package]]
name = "once_cell" name = "once_cell"
version = "1.10.0" version = "1.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" checksum = "074864da206b4973b84eb91683020dbefd6a8c3f0f38e054d93954e891935e4e"
[[package]] [[package]]
name = "predicates" name = "predicates"
@ -399,52 +398,52 @@ dependencies = [
[[package]] [[package]]
name = "predicates-core" name = "predicates-core"
version = "1.0.2" version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57e35a3326b75e49aa85f5dc6ec15b41108cf5aee58eabb1f274dd18b73c2451" checksum = "da1c2388b1513e1b605fcec39a95e0a9e8ef088f71443ef37099fa9ae6673fcb"
[[package]] [[package]]
name = "predicates-tree" name = "predicates-tree"
version = "1.0.3" version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7dd0fd014130206c9352efbdc92be592751b2b9274dff685348341082c6ea3d" checksum = "4d86de6de25020a36c6d3643a86d9a6a9f552107c0559c60ea03551b5e16c032"
dependencies = [ dependencies = [
"predicates-core", "predicates-core",
"treeline", "termtree",
] ]
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.28" version = "1.0.43"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612" checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab"
dependencies = [ dependencies = [
"unicode-xid", "unicode-ident",
] ]
[[package]] [[package]]
name = "quote" name = "quote"
version = "1.0.9" version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
] ]
[[package]] [[package]]
name = "redox_syscall" name = "redox_syscall"
version = "0.2.10" version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
dependencies = [ dependencies = [
"bitflags", "bitflags",
] ]
[[package]] [[package]]
name = "regex" name = "regex"
version = "1.5.5" version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286" checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b"
dependencies = [ dependencies = [
"aho-corasick", "aho-corasick",
"memchr", "memchr",
@ -453,13 +452,13 @@ dependencies = [
[[package]] [[package]]
name = "regex-syntax" name = "regex-syntax"
version = "0.6.25" version = "0.6.27"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244"
[[package]] [[package]]
name = "rustlings" name = "rustlings"
version = "5.0.0" version = "5.1.1"
dependencies = [ dependencies = [
"argh", "argh",
"assert_cmd", "assert_cmd",
@ -477,9 +476,9 @@ dependencies = [
[[package]] [[package]]
name = "ryu" name = "ryu"
version = "1.0.5" version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
[[package]] [[package]]
name = "same-file" name = "same-file"
@ -492,18 +491,18 @@ dependencies = [
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.129" version = "1.0.144"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d1f72836d2aa753853178eda473a3b9d8e4eefdaf20523b919677e6de489f8f1" checksum = "0f747710de3dcd43b88c9168773254e809d8ddbdf9653b84e2554ab219f17860"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.129" version = "1.0.144"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e57ae87ad533d9a56427558b516d0adac283614e347abf85b0dc0cbbf0a249f3" checksum = "94ed3a816fb1d101812f83e789f888322c34e291f894f19590dc310963e87a00"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -512,9 +511,9 @@ dependencies = [
[[package]] [[package]]
name = "serde_json" name = "serde_json"
version = "1.0.81" version = "1.0.85"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c" checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44"
dependencies = [ dependencies = [
"itoa", "itoa",
"ryu", "ryu",
@ -523,19 +522,22 @@ dependencies = [
[[package]] [[package]]
name = "slab" name = "slab"
version = "0.4.4" version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c307a32c1c5c437f38c7fd45d753050587732ba8628319fbdf12a7e289ccc590" checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef"
dependencies = [
"autocfg",
]
[[package]] [[package]]
name = "syn" name = "syn"
version = "1.0.75" version = "1.0.99"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7f58f7e8eaa0009c5fec437aabf511bd9933e4b2d7407bd05273c01a8906ea7" checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"unicode-xid", "unicode-ident",
] ]
[[package]] [[package]]
@ -548,6 +550,12 @@ dependencies = [
"winapi 0.3.9", "winapi 0.3.9",
] ]
[[package]]
name = "termtree"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "507e9898683b6c43a9aa55b64259b721b52ba226e0f3779137e50ad114a4c90b"
[[package]] [[package]]
name = "toml" name = "toml"
version = "0.5.9" version = "0.5.9"
@ -558,28 +566,22 @@ dependencies = [
] ]
[[package]] [[package]]
name = "treeline" name = "unicode-ident"
version = "0.1.0" version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7f741b240f1a48843f9b8e0444fb55fb2a4ff67293b50a9179dfd5ea67f8d41" checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf"
[[package]] [[package]]
name = "unicode-segmentation" name = "unicode-segmentation"
version = "1.8.0" version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99"
[[package]] [[package]]
name = "unicode-width" name = "unicode-width"
version = "0.1.8" version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
[[package]]
name = "unicode-xid"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
[[package]] [[package]]
name = "walkdir" name = "walkdir"
@ -635,6 +637,49 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-sys"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2"
dependencies = [
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_msvc"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47"
[[package]]
name = "windows_i686_gnu"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6"
[[package]]
name = "windows_i686_msvc"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024"
[[package]]
name = "windows_x86_64_gnu"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1"
[[package]]
name = "windows_x86_64_msvc"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680"
[[package]] [[package]]
name = "ws2_32-sys" name = "ws2_32-sys"
version = "0.2.1" version = "0.2.1"

View File

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

View File

@ -54,11 +54,11 @@ If you get a permission denied message, you might have to exclude the directory
## Manually ## Manually
Basically: Clone the repository at the latest tag, run `cargo install`. Basically: Clone the repository at the latest tag, run `cargo install --path .`.
```bash ```bash
# find out the latest version at https://github.com/rust-lang/rustlings/releases/latest (on edit 5.0.0) # find out the latest version at https://github.com/rust-lang/rustlings/releases/latest (on edit 5.1.1)
git clone -b 5.0.0 --depth 1 https://github.com/rust-lang/rustlings git clone -b 5.1.1 --depth 1 https://github.com/rust-lang/rustlings
cd rustlings cd rustlings
cargo install --force --path . cargo install --force --path .
``` ```
@ -154,6 +154,10 @@ Now you should be done!
See [CONTRIBUTING.md](./CONTRIBUTING.md). See [CONTRIBUTING.md](./CONTRIBUTING.md).
Development-focused discussion about Rustlings happens in the [**rustlings** stream](https://rust-lang.zulipchat.com/#narrow/stream/334454-rustlings)
on the [Rust Project Zulip](https://rust-lang.zulipchat.com). Feel free to start a new thread there
if you have ideas or suggestions!
## Contributors ✨ ## Contributors ✨
Thanks goes to the wonderful people listed in [AUTHORS.md](./AUTHORS.md) 🎉 Thanks goes to the wonderful people listed in [AUTHORS.md](./AUTHORS.md) 🎉

View File

@ -4,6 +4,8 @@
// This exercise uses some concepts that we won't get to until later in the course, like `Box` and the // 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. // `From` trait. It's not important to understand them in detail right now, but you can read ahead if you like.
// For now, think of the `Box<dyn ...>` type as an "I want anything that does ???" type, which, given
// Rust's usual standards for runtime safety, should strike you as somewhat lenient!
// 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 // 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 // type which implements a particular trait. To do so, The Box is declared as of type Box<dyn Trait> where Trait is the trait

View File

@ -7,4 +7,4 @@ macros. Instead, we'll show you how to use and create them.
## Further information ## Further information
- [Macros](https://doc.rust-lang.org/book/ch19-06-macros.html) - [Macros](https://doc.rust-lang.org/book/ch19-06-macros.html)
- [The Little Book of Rust Macros](https://danielkeep.github.io/tlborm/book/index.html) - [The Little Book of Rust Macros](https://veykril.github.io/tlborm/)

View File

@ -3,17 +3,13 @@
// I AM NOT DONE // 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. // 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 // If it's before 10PM, there's 5 pieces left. At 10PM, someone eats them
// all, so there'll be no more left :( // all, so there'll be no more left :(
// TODO: Return an Option! // TODO: Return an Option!
fn maybe_icecream(time_of_day: u16) -> Option<u16> { fn maybe_icecream(time_of_day: u16) -> Option<u16> {
// We use the 24-hour system here, so 10PM is a value of 22 // We use the 24-hour system here, so 10PM is a value of 22
// The Option output should gracefully handle cases where time_of_day > 24.
??? ???
} }
@ -23,9 +19,11 @@ mod tests {
#[test] #[test]
fn check_icecream() { fn check_icecream() {
assert_eq!(maybe_icecream(9), Some(5));
assert_eq!(maybe_icecream(10), Some(5)); assert_eq!(maybe_icecream(10), Some(5));
assert_eq!(maybe_icecream(23), None); assert_eq!(maybe_icecream(23), Some(0));
assert_eq!(maybe_icecream(22), None); assert_eq!(maybe_icecream(22), Some(0));
assert_eq!(maybe_icecream(25), None);
} }
#[test] #[test]

View File

@ -3,23 +3,34 @@
// I AM NOT DONE // I AM NOT DONE
fn main() { #[cfg(test)]
let optional_word = Some(String::from("rustlings")); mod tests {
// TODO: Make this an if let statement whose value is "Some" type use super::*;
word = optional_word {
println!("The word is: {}", word); #[test]
} else { fn simple_option() {
println!("The optional word doesn't contain anything"); let target = "rustlings";
let optional_target = Some(target);
// TODO: Make this an if let statement whose value is "Some" type
word = optional_target {
assert_eq!(word, target);
}
} }
let mut optional_integers_vec: Vec<Option<i8>> = Vec::new(); #[test]
for x in 1..10 { fn layered_option() {
optional_integers_vec.push(Some(x)); let mut range = 10;
} let mut optional_integers: Vec<Option<i8>> = Vec::new();
for i in 0..(range + 1) {
optional_integers.push(Some(i));
}
// TODO: make this a while let statement - remember that vector.pop also adds another layer of Option<T> // TODO: make this a while let statement - remember that vector.pop also adds another layer of Option<T>
// You can stack `Option<T>`'s into while let and if let // You can stack `Option<T>`'s into while let and if let
integer = optional_integers_vec.pop() { integer = optional_integers.pop() {
println!("current value: {}", integer); assert_eq!(integer, range);
range -= 1;
}
} }
} }

View File

@ -42,7 +42,7 @@ mod my_module {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
// TODO: What to we have to import to have `transformer` in scope? // TODO: What do we have to import to have `transformer` in scope?
use ???; use ???;
use super::Command; use super::Command;

View File

@ -10,7 +10,7 @@
// elements: the value of the current item and the next item. The last item is a value called `Nil`. // elements: the value of the current item and the next item. The last item is a value called `Nil`.
// //
// Step 1: use a `Box` in the enum definition to make the code compile // Step 1: use a `Box` in the enum definition to make the code compile
// Step 2: create both empty and non-empty cons lists by replacing `unimplemented!()` // Step 2: create both empty and non-empty cons lists by replacing `todo!()`
// //
// Note: the tests should not be changed // Note: the tests should not be changed
// //
@ -33,11 +33,11 @@ fn main() {
} }
pub fn create_empty_list() -> List { pub fn create_empty_list() -> List {
unimplemented!() todo!()
} }
pub fn create_non_empty_list() -> List { pub fn create_non_empty_list() -> List {
unimplemented!() todo!()
} }
#[cfg(test)] #[cfg(test)]

View File

@ -0,0 +1,48 @@
// cow1.rs
// This exercise explores the Cow, or Clone-On-Write type.
// Cow is a clone-on-write smart pointer.
// It can enclose and provide immutable access to borrowed data, and clone the data lazily when mutation or ownership is required.
// The type is designed to work with general borrowed data via the Borrow trait.
// I AM NOT DONE
use std::borrow::Cow;
fn abs_all<'a, 'b>(input: &'a mut Cow<'b, [i32]>) -> &'a mut Cow<'b, [i32]> {
for i in 0..input.len() {
let v = input[i];
if v < 0 {
// Clones into a vector if not already owned.
input.to_mut()[i] = -v;
}
}
input
}
fn main() {
// No clone occurs because `input` doesn't need to be mutated.
let slice = [0, 1, 2];
let mut input = Cow::from(&slice[..]);
match abs_all(&mut input) {
Cow::Borrowed(_) => println!("I borrowed the slice!"),
_ => panic!("expected borrowed value"),
}
// Clone occurs because `input` needs to be mutated.
let slice = [-1, 0, 1];
let mut input = Cow::from(&slice[..]);
match abs_all(&mut input) {
Cow::Owned(_) => println!("I modified the slice and now own it!"),
_ => panic!("expected owned value"),
}
// No clone occurs because `input` is already owned.
let slice = vec![-1, 0, 1];
let mut input = Cow::from(slice);
match abs_all(&mut input) {
// TODO
Cow::Borrowed(_) => println!("I own this slice!"),
_ => panic!("expected borrowed value"),
}
}

View File

@ -0,0 +1,98 @@
// rc1.rs
// In this exercise, we want to express the concept of multiple owners via the Rc<T> type.
// This is a model of our solar system - there is a Sun type and multiple Planets.
// The Planets take ownership of the sun, indicating that they revolve around the sun.
// Make this code compile by using the proper Rc primitives to express that the sun has multiple owners.
// I AM NOT DONE
use std::rc::Rc;
#[derive(Debug)]
struct Sun {}
#[derive(Debug)]
enum Planet {
Mercury(Rc<Sun>),
Venus(Rc<Sun>),
Earth(Rc<Sun>),
Mars(Rc<Sun>),
Jupiter(Rc<Sun>),
Saturn(Rc<Sun>),
Uranus(Rc<Sun>),
Neptune(Rc<Sun>),
}
impl Planet {
fn details(&self) {
println!("Hi from {:?}!", self)
}
}
fn main() {
let sun = Rc::new(Sun {});
println!("reference count = {}", Rc::strong_count(&sun)); // 1 reference
let mercury = Planet::Mercury(Rc::clone(&sun));
println!("reference count = {}", Rc::strong_count(&sun)); // 2 references
mercury.details();
let venus = Planet::Venus(Rc::clone(&sun));
println!("reference count = {}", Rc::strong_count(&sun)); // 3 references
venus.details();
let earth = Planet::Earth(Rc::clone(&sun));
println!("reference count = {}", Rc::strong_count(&sun)); // 4 references
earth.details();
let mars = Planet::Mars(Rc::clone(&sun));
println!("reference count = {}", Rc::strong_count(&sun)); // 5 references
mars.details();
let jupiter = Planet::Jupiter(Rc::clone(&sun));
println!("reference count = {}", Rc::strong_count(&sun)); // 6 references
jupiter.details();
// TODO
let saturn = Planet::Saturn(Rc::new(Sun {}));
println!("reference count = {}", Rc::strong_count(&sun)); // 7 references
saturn.details();
// TODO
let uranus = Planet::Uranus(Rc::new(Sun {}));
println!("reference count = {}", Rc::strong_count(&sun)); // 8 references
uranus.details();
// TODO
let neptune = Planet::Neptune(Rc::new(Sun {}));
println!("reference count = {}", Rc::strong_count(&sun)); // 9 references
neptune.details();
assert_eq!(Rc::strong_count(&sun), 9);
drop(neptune);
println!("reference count = {}", Rc::strong_count(&sun)); // 8 references
drop(uranus);
println!("reference count = {}", Rc::strong_count(&sun)); // 7 references
drop(saturn);
println!("reference count = {}", Rc::strong_count(&sun)); // 6 references
drop(jupiter);
println!("reference count = {}", Rc::strong_count(&sun)); // 5 references
drop(mars);
println!("reference count = {}", Rc::strong_count(&sun)); // 4 references
// TODO
println!("reference count = {}", Rc::strong_count(&sun)); // 3 references
// TODO
println!("reference count = {}", Rc::strong_count(&sun)); // 2 references
// TODO
println!("reference count = {}", Rc::strong_count(&sun)); // 1 reference
assert_eq!(Rc::strong_count(&sun), 1);
}

View File

@ -4,7 +4,7 @@
// I AM NOT DONE // I AM NOT DONE
fn trim_me(input: &str) -> String { fn trim_me(input: &str) -> String {
// TODO: Remove whitespace from the end of a string! // TODO: Remove whitespace from both ends of a string!
??? ???
} }

View File

@ -1,7 +1,7 @@
// traits4.rs // traits4.rs
// //
// Your task is to replace the '??' sections so the code compiles. // Your task is to replace the '??' sections so the code compiles.
// Don't change any line other than 21. // Don't change any line other than the marked one.
// Execute `rustlings hint traits4` or use the `hint` watch subcommand for a hint. // Execute `rustlings hint traits4` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE // I AM NOT DONE
@ -19,6 +19,7 @@ struct OtherSoftware {}
impl Licensed for SomeSoftware {} impl Licensed for SomeSoftware {}
impl Licensed for OtherSoftware {} impl Licensed for OtherSoftware {}
// YOU MAY ONLY CHANGE THE NEXT LINE
fn compare_license_types(software: ??, software_two: ??) -> bool { fn compare_license_types(software: ??, software_two: ??) -> bool {
software.licensing_info() == software_two.licensing_info() software.licensing_info() == software_two.licensing_info()
} }

View File

@ -1,7 +1,7 @@
// traits5.rs // traits5.rs
// //
// Your task is to replace the '??' sections so the code compiles. // Your task is to replace the '??' sections so the code compiles.
// Don't change any line other than 27. // Don't change any line other than the marked one.
// Execute `rustlings hint traits5` or use the `hint` watch subcommand for a hint. // Execute `rustlings hint traits5` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE // I AM NOT DONE
@ -18,15 +18,20 @@ pub trait OtherTrait {
} }
} }
struct SomeStruct { struct SomeStruct {}
name: String, struct OtherStruct {}
}
impl SomeTrait for SomeStruct {} impl SomeTrait for SomeStruct {}
impl OtherTrait for SomeStruct {} impl OtherTrait for SomeStruct {}
impl SomeTrait for OtherStruct {}
impl OtherTrait for OtherStruct {}
// YOU MAY ONLY CHANGE THE NEXT LINE
fn some_func(item: ??) -> bool { fn some_func(item: ??) -> bool {
item.some_function() && item.other_function() item.some_function() && item.other_function()
} }
fn main() {} fn main() {
some_func(SomeStruct {});
some_func(OtherStruct {});
}

View File

@ -63,7 +63,7 @@ name = "variables5"
path = "exercises/variables/variables5.rs" path = "exercises/variables/variables5.rs"
mode = "compile" mode = "compile"
hint = """ hint = """
In variables3 we already learned how to make an immutable variable mutable In variables4 we already learned how to make an immutable variable mutable
using a special keyword. Unfortunately this doesn't help us much in this exercise using a special keyword. Unfortunately this doesn't help us much in this exercise
because we want to assign a different typed value to an existing variable. Sometimes because we want to assign a different typed value to an existing variable. Sometimes
you may also like to reuse existing variable names because you are just converting you may also like to reuse existing variable names because you are just converting
@ -123,8 +123,8 @@ name = "functions4"
path = "exercises/functions/functions4.rs" path = "exercises/functions/functions4.rs"
mode = "compile" mode = "compile"
hint = """ hint = """
The error message points to line 14 and says it expects a type after the The error message points to line 17 and says it expects a type after the
`->`. This is where the function's return type should be-- take a look at `->`. This is where the function's return type should be -- take a look at
the `is_even` function for an example! the `is_even` function for an example!
Also: Did you figure out that, technically, u32 would be the more fitting type Also: Did you figure out that, technically, u32 would be the more fitting type
@ -545,7 +545,7 @@ is the easiest, but how do you do it safely so that it doesn't panic in your fac
[[exercises]] [[exercises]]
name = "options2" name = "options2"
path = "exercises/options/options2.rs" path = "exercises/options/options2.rs"
mode = "compile" mode = "test"
hint = """ hint = """
check out: check out:
https://doc.rust-lang.org/rust-by-example/flow_control/if_let.html https://doc.rust-lang.org/rust-by-example/flow_control/if_let.html
@ -732,7 +732,7 @@ name = "traits5"
path = "exercises/traits/traits5.rs" path = "exercises/traits/traits5.rs"
mode = "compile" mode = "compile"
hint = """ hint = """
To ensure a paramter implements multiple traits use the '+ syntax'. Try replacing the To ensure a parameter implements multiple traits use the '+ syntax'. Try replacing the
'??' with 'impl <> + <>'. '??' with 'impl <> + <>'.
See the documentation at: https://doc.rust-lang.org/book/ch10-02-traits.html#specifying-multiple-trait-bounds-with-the--syntax See the documentation at: https://doc.rust-lang.org/book/ch10-02-traits.html#specifying-multiple-trait-bounds-with-the--syntax
@ -746,7 +746,7 @@ path = "exercises/quiz3.rs"
mode = "test" mode = "test"
hint = """ hint = """
To find the best solution to this challenge you're going to need to think back to your To find the best solution to this challenge you're going to need to think back to your
knowledge of traits, specifically Trait Bound Syntax - you may also need this: "use std::fmt::Display;"""" knowledge of traits, specifically Trait Bound Syntax - you may also need this: `use std::fmt::Display;`."""
# TESTS # TESTS
@ -795,7 +795,10 @@ name = "lifetimes2"
path = "exercises/lifetimes/lifetimes2.rs" path = "exercises/lifetimes/lifetimes2.rs"
mode = "compile" mode = "compile"
hint = """ hint = """
What is the compiler checking? How could you change how long an owned variable lives?""" Remember that the generic lifetime 'a will get the concrete lifetime that is equal to the smaller of the lifetimes of x and y.
You can take at least two paths to achieve the desired result while keeping the inner block:
1. Move the string2 declaration to make it live as long as string1 (how is result declared?)
2. Move println! into the inner block"""
[[exercises]] [[exercises]]
name = "lifetimes3" name = "lifetimes3"
@ -929,6 +932,31 @@ is too much of a struggle, consider reading through all of Chapter 16 in the boo
https://doc.rust-lang.org/stable/book/ch16-00-concurrency.html https://doc.rust-lang.org/stable/book/ch16-00-concurrency.html
""" """
[[exercises]]
name = "rc1"
path = "exercises/standard_library_types/rc1.rs"
mode = "compile"
hint = """
This is a straightforward exercise to use the Rc<T> type. Each Planet has
ownership of the Sun, and uses Rc::clone() to increment the reference count of the Sun.
After using drop() to move the Planets out of scope individually, the reference count goes down.
In the end the sun only has one reference again, to itself. See more at:
https://doc.rust-lang.org/book/ch15-04-rc.html
* Unforunately Pluto is no longer considered a planet :(
"""
[[exercises]]
name = "cow1"
path = "exercises/standard_library_types/cow1.rs"
mode = "compile"
hint = """
Since the vector is already owned, the `Cow` type doesn't need to clone it.
Checkout https://doc.rust-lang.org/std/borrow/enum.Cow.html for documentation
on the `Cow` type.
"""
# THREADS # THREADS
[[exercises]] [[exercises]]
@ -985,7 +1013,7 @@ An alternate way to handle concurrency between threads is to use
a mpsc (multiple producer, single consumer) channel to communicate. a mpsc (multiple producer, single consumer) channel to communicate.
With both a sending end and a receiving end, it's possible to With both a sending end and a receiving end, it's possible to
send values in one thread and receieve them in another. send values in one thread and receieve them in another.
Multiple producers are possibile by using clone() to create a duplicate Multiple producers are possible by using clone() to create a duplicate
of the original sending end. of the original sending end.
See https://doc.rust-lang.org/book/ch16-02-message-passing.html for more info. See https://doc.rust-lang.org/book/ch16-02-message-passing.html for more info.
""" """

View File

@ -1,6 +1,6 @@
use crate::exercise::{Exercise, ExerciseList}; use crate::exercise::{Exercise, ExerciseList};
use crate::project::RustAnalyzerProject; use crate::project::RustAnalyzerProject;
use crate::run::run; use crate::run::{reset, run};
use crate::verify::verify; use crate::verify::verify;
use argh::FromArgs; use argh::FromArgs;
use console::Emoji; use console::Emoji;
@ -26,7 +26,7 @@ mod run;
mod verify; mod verify;
// In sync with crate version // In sync with crate version
const VERSION: &str = "5.0.0"; const VERSION: &str = "5.1.1";
#[derive(FromArgs, PartialEq, Debug)] #[derive(FromArgs, PartialEq, Debug)]
/// Rustlings is a collection of small exercises to get you used to writing and reading Rust code /// Rustlings is a collection of small exercises to get you used to writing and reading Rust code
@ -47,6 +47,7 @@ enum Subcommands {
Verify(VerifyArgs), Verify(VerifyArgs),
Watch(WatchArgs), Watch(WatchArgs),
Run(RunArgs), Run(RunArgs),
Reset(ResetArgs),
Hint(HintArgs), Hint(HintArgs),
List(ListArgs), List(ListArgs),
Lsp(LspArgs), Lsp(LspArgs),
@ -71,6 +72,15 @@ struct RunArgs {
name: String, name: String,
} }
#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "reset")]
/// Resets a single exercise using "git stash -- <filename>"
struct ResetArgs {
#[argh(positional)]
/// the name of the exercise
name: String,
}
#[derive(FromArgs, PartialEq, Debug)] #[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "hint")] #[argh(subcommand, name = "hint")]
/// Returns a hint for the given exercise /// Returns a hint for the given exercise
@ -85,7 +95,6 @@ struct HintArgs {
/// Enable rust-analyzer for exercises /// Enable rust-analyzer for exercises
struct LspArgs {} struct LspArgs {}
#[derive(FromArgs, PartialEq, Debug)] #[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "list")] #[argh(subcommand, name = "list")]
/// Lists the exercises available in Rustlings /// Lists the exercises available in Rustlings
@ -164,7 +173,9 @@ fn main() {
"Pending" "Pending"
}; };
let solve_cond = { let solve_cond = {
(e.looks_done() && subargs.solved) || (!e.looks_done() && subargs.unsolved) || (!subargs.solved && !subargs.unsolved) (e.looks_done() && subargs.solved)
|| (!e.looks_done() && subargs.unsolved)
|| (!subargs.solved && !subargs.unsolved)
}; };
if solve_cond && (filter_cond || subargs.filter.is_none()) { if solve_cond && (filter_cond || subargs.filter.is_none()) {
let line = if subargs.paths { let line = if subargs.paths {
@ -205,6 +216,12 @@ fn main() {
run(exercise, verbose).unwrap_or_else(|_| std::process::exit(1)); run(exercise, verbose).unwrap_or_else(|_| std::process::exit(1));
} }
Subcommands::Reset(subargs) => {
let exercise = find_exercise(&subargs.name, &exercises);
reset(exercise).unwrap_or_else(|_| std::process::exit(1));
}
Subcommands::Hint(subargs) => { Subcommands::Hint(subargs) => {
let exercise = find_exercise(&subargs.name, &exercises); let exercise = find_exercise(&subargs.name, &exercises);
@ -212,7 +229,8 @@ fn main() {
} }
Subcommands::Verify(_subargs) => { Subcommands::Verify(_subargs) => {
verify(&exercises, (0, exercises.len()), verbose).unwrap_or_else(|_| std::process::exit(1)); verify(&exercises, (0, exercises.len()), verbose)
.unwrap_or_else(|_| std::process::exit(1));
} }
Subcommands::Lsp(_subargs) => { Subcommands::Lsp(_subargs) => {
@ -236,12 +254,18 @@ fn main() {
Subcommands::Watch(_subargs) => match watch(&exercises, verbose) { Subcommands::Watch(_subargs) => match watch(&exercises, verbose) {
Err(e) => { 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."); println!("Most likely you've run out of disk space or your 'inotify limit' has been reached.");
std::process::exit(1); std::process::exit(1);
} }
Ok(WatchStatus::Finished) => { Ok(WatchStatus::Finished) => {
println!("{emoji} All exercises completed! {emoji}", emoji = Emoji("🎉", "")); println!(
"{emoji} All exercises completed! {emoji}",
emoji = Emoji("🎉", "")
);
println!("\n{}\n", FENISH_LINE); println!("\n{}\n", FENISH_LINE);
} }
Ok(WatchStatus::Unfinished) => { Ok(WatchStatus::Unfinished) => {
@ -252,8 +276,10 @@ fn main() {
} }
} }
fn spawn_watch_shell(
fn spawn_watch_shell(failed_exercise_hint: &Arc<Mutex<Option<String>>>, should_quit: Arc<AtomicBool>) { failed_exercise_hint: &Arc<Mutex<Option<String>>>,
should_quit: Arc<AtomicBool>,
) {
let failed_exercise_hint = Arc::clone(failed_exercise_hint); 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."); println!("Welcome to watch mode! You can type 'help' to get an overview of the commands you can use here.");
thread::spawn(move || loop { thread::spawn(move || loop {
@ -290,16 +316,22 @@ fn spawn_watch_shell(failed_exercise_hint: &Arc<Mutex<Option<String>>>, should_q
fn find_exercise<'a>(name: &str, exercises: &'a [Exercise]) -> &'a Exercise { fn find_exercise<'a>(name: &str, exercises: &'a [Exercise]) -> &'a Exercise {
if name.eq("next") { if name.eq("next") {
exercises.iter().find(|e| !e.looks_done()).unwrap_or_else(|| { exercises
println!("🎉 Congratulations! You have done all the exercises!"); .iter()
println!("🔚 There are no more exercises to do next!"); .find(|e| !e.looks_done())
std::process::exit(1) .unwrap_or_else(|| {
}) println!("🎉 Congratulations! You have done all the exercises!");
println!("🔚 There are no more exercises to do next!");
std::process::exit(1)
})
} else { } else {
exercises.iter().find(|e| e.name == name).unwrap_or_else(|| { exercises
println!("No exercise found for '{}'!", name); .iter()
std::process::exit(1) .find(|e| e.name == name)
}) .unwrap_or_else(|| {
println!("No exercise found for '{}'!", name);
std::process::exit(1)
})
} }
} }
@ -337,8 +369,13 @@ fn watch(exercises: &[Exercise], verbose: bool) -> notify::Result<WatchStatus> {
let filepath = b.as_path().canonicalize().unwrap(); let filepath = b.as_path().canonicalize().unwrap();
let pending_exercises = exercises let pending_exercises = exercises
.iter() .iter()
.find(|e| filepath.ends_with(&e.path)).into_iter() .find(|e| filepath.ends_with(&e.path))
.chain(exercises.iter().filter(|e| !e.looks_done() && !filepath.ends_with(&e.path))); .into_iter()
.chain(
exercises
.iter()
.filter(|e| !e.looks_done() && !filepath.ends_with(&e.path)),
);
let num_done = exercises.iter().filter(|e| e.looks_done()).count(); let num_done = exercises.iter().filter(|e| e.looks_done()).count();
clear_screen(); clear_screen();
match verify(pending_exercises, (num_done, exercises.len()), verbose) { match verify(pending_exercises, (num_done, exercises.len()), verbose) {

View File

@ -1,3 +1,5 @@
use std::process::Command;
use crate::exercise::{Exercise, Mode}; use crate::exercise::{Exercise, Mode};
use crate::verify::test; use crate::verify::test;
use indicatif::ProgressBar; use indicatif::ProgressBar;
@ -15,6 +17,19 @@ pub fn run(exercise: &Exercise, verbose: bool) -> Result<(), ()> {
Ok(()) Ok(())
} }
// Resets the exercise by stashing the changes.
pub fn reset(exercise: &Exercise) -> Result<(), ()> {
let command = Command::new("git")
.args(["stash", "--"])
.arg(&exercise.path)
.spawn();
match command {
Ok(_) => Ok(()),
Err(_) => Err(()),
}
}
// Invoke the rust compiler on the path of the given exercise // Invoke the rust compiler on the path of the given exercise
// and run the ensuing binary. // and run the ensuing binary.
// This is strictly for non-test binaries, so output is displayed // This is strictly for non-test binaries, so output is displayed

View File

@ -110,6 +110,27 @@ fn run_single_test_no_exercise() {
.code(1); .code(1);
} }
#[test]
fn reset_single_exercise() {
Command::cargo_bin("rustlings")
.unwrap()
.args(&["reset", "intro1"])
.assert()
.code(0);
}
#[test]
fn reset_no_exercise() {
Command::cargo_bin("rustlings")
.unwrap()
.arg("reset")
.assert()
.code(1)
.stderr(predicates::str::contains(
"positional arguments not provided",
));
}
#[test] #[test]
fn get_hint_for_single_test() { fn get_hint_for_single_test() {
Command::cargo_bin("rustlings") Command::cargo_bin("rustlings")
@ -126,7 +147,7 @@ fn all_exercises_require_confirmation() {
for exercise in glob("exercises/**/*.rs").unwrap() { for exercise in glob("exercises/**/*.rs").unwrap() {
let path = exercise.unwrap(); let path = exercise.unwrap();
if path.file_name().unwrap() == "mod.rs" { if path.file_name().unwrap() == "mod.rs" {
continue continue;
} }
let source = { let source = {
let mut file = File::open(&path).unwrap(); let mut file = File::open(&path).unwrap();
@ -176,7 +197,7 @@ fn run_single_test_success_with_output() {
.current_dir("tests/fixture/success/") .current_dir("tests/fixture/success/")
.assert() .assert()
.code(0) .code(0)
.stdout(predicates::str::contains("THIS TEST TOO SHALL PAS")); .stdout(predicates::str::contains("THIS TEST TOO SHALL PASS"));
} }
#[test] #[test]
@ -187,7 +208,7 @@ fn run_single_test_success_without_output() {
.current_dir("tests/fixture/success/") .current_dir("tests/fixture/success/")
.assert() .assert()
.code(0) .code(0)
.stdout(predicates::str::contains("THIS TEST TOO SHALL PAS").not()); .stdout(predicates::str::contains("THIS TEST TOO SHALL PASS").not());
} }
#[test] #[test]