Compare commits
171 commits
all-contri
...
main
Author | SHA1 | Date | |
---|---|---|---|
red | 84bb490545 | ||
red | aa2ce0ee19 | ||
red | f1bf7b5735 | ||
red | f81fe2b60c | ||
red | 5b989095cd | ||
cdd8e19716 | |||
91d86a1de9 | |||
6a10f900b4 | |||
9b9a89c79a | |||
123e6426d1 | |||
427ec6b2e4 | |||
03dcb582e6 | |||
1043a06124 | |||
d20e413a68 | |||
9bf4c5e8df | |||
633303d4b8 | |||
a4a1098766 | |||
0bd459dcac | |||
3b4514b686 | |||
2e05606edc | |||
c8c1b87a01 | |||
34ea029df8 | |||
3a4433d5a2 | |||
de6c45ad24 | |||
fadade8592 | |||
d91044f3a2 | |||
a3ea37b76e | |||
ec63cadadb | |||
84d8305730 | |||
73777980f1 | |||
75788b1148 | |||
dd9b2ddc89 | |||
b7ddd09fab | |||
48ffcbd2c4 | |||
68d3ac567c | |||
50ab289da6 | |||
4e079fdd08 | |||
91fc9e3118 | |||
a2f0401c4c | |||
1b85828548 | |||
4c46e5e1a3 | |||
4da9e7ee29 | |||
72e615aa7a | |||
cd02abc481 | |||
399ab328d8 | |||
809ec2ce01 | |||
11d2cf0d60 | |||
dbb2624403 | |||
4d4fa77459 | |||
3145794084 | |||
d9b69bd1a0 | |||
7cd635fa84 | |||
ce40e201f0 | |||
404f3ef465 | |||
e1be594fdd | |||
9569c9a9e7 | |||
91530f5716 | |||
650b1dee54 | |||
6b6dc9dd48 | |||
3a9ec4192d | |||
4f7dbbd2c3 | |||
8c37db1a23 | |||
c6b7ad8878 | |||
84461c20cb | |||
3cddda56fc | |||
37f3069a67 | |||
2b2fbe918e | |||
cf42ddc449 | |||
eefa656232 | |||
249ad44cc0 | |||
54804e344d | |||
1c334de6fd | |||
f253103a31 | |||
1120db57a6 | |||
afa661cff4 | |||
347f30bd86 | |||
127773f3f5 | |||
8d0490bd70 | |||
293dfb35d5 | |||
81be404487 | |||
6177b6e126 | |||
79cc657917 | |||
7928122fce | |||
9c88ea9126 | |||
2b766ef9f9 | |||
bd3d9ac9d5 | |||
aa0db8379c | |||
eadd41a9ec | |||
fab2eb9833 | |||
6bd791f2f4 | |||
ec5f80dce1 | |||
65cdc856ae | |||
472f61485e | |||
b4de659438 | |||
a37a8818c8 | |||
bdf01aa174 | |||
a941c69f09 | |||
72aaa15e6a | |||
3a06de71a8 | |||
5e2b39a5c1 | |||
63c942233e | |||
2612edc133 | |||
e2ce9f42b5 | |||
1c6f7e4b7b | |||
e2c41903ad | |||
bd48544e25 | |||
c0e3daacaf | |||
f2ad3a6a0b | |||
caf921a01f | |||
b790bafc02 | |||
ad3cd54cce | |||
1a6a725f88 | |||
1ad20d94ff | |||
995c6f0fb1 | |||
c3e7b83178 | |||
2e93a588e0 | |||
9aeca3f97e | |||
2193fff4bb | |||
aec2c65c63 | |||
a6509cc4d5 | |||
a02b279750 | |||
ece841f5ce | |||
2a6e4dc8a6 | |||
c163011cc0 | |||
b350945a16 | |||
1ef368a69d | |||
8dc587b01a | |||
550c4293ed | |||
3df094713f | |||
01e7f27aa6 | |||
8d62a99637 | |||
ab9995e76e | |||
bef39b1259 | |||
0d894e6ff7 | |||
be9510539e | |||
3bce2ef8d6 | |||
aa9a943ddf | |||
ebdb66c7bf | |||
9f3e8c2dde | |||
96c56ab08a | |||
04dbf03ace | |||
05a753fe63 | |||
815edb7003 | |||
5157f56875 | |||
3f5abca215 | |||
833df0b8b3 | |||
6742860ea5 | |||
797e6d45c0 | |||
320de0d921 | |||
5eed505d74 | |||
91ee27f22b | |||
5f7c89f85d | |||
c6712dfccd | |||
baf4ba175b | |||
b29ea17ea9 | |||
ab57c26cf9 | |||
98e5e8835e | |||
f5158ece1a | |||
d65b4a9a93 | |||
8404947bc0 | |||
2e84f34cf3 | |||
726805f064 | |||
b4a4138559 | |||
f1d2b3a39a | |||
1f9d006858 | |||
cc266d7d80 | |||
fff72afe2e | |||
c1abd13b5c | |||
75802c14b2 | |||
cddc1e86e7 | |||
24ea42ce61 |
|
@ -683,6 +683,234 @@
|
||||||
"content",
|
"content",
|
||||||
"code"
|
"code"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "jbaber",
|
||||||
|
"name": "John Baber-Lucero",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/1908117?v=4",
|
||||||
|
"profile": "https://github.com/jbaber",
|
||||||
|
"contributions": [
|
||||||
|
"content"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "tal-zvon",
|
||||||
|
"name": "Tal",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/3195851?v=4",
|
||||||
|
"profile": "https://github.com/tal-zvon",
|
||||||
|
"contributions": [
|
||||||
|
"content"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "apogeeoak",
|
||||||
|
"name": "apogeeoak",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/59737221?v=4",
|
||||||
|
"profile": "https://github.com/apogeeoak",
|
||||||
|
"contributions": [
|
||||||
|
"content",
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "Crell",
|
||||||
|
"name": "Larry Garfield",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/254863?v=4",
|
||||||
|
"profile": "http://www.garfieldtech.com/",
|
||||||
|
"contributions": [
|
||||||
|
"content"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "circumspect",
|
||||||
|
"name": "circumspect",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/40770208?v=4",
|
||||||
|
"profile": "https://github.com/circumspect",
|
||||||
|
"contributions": [
|
||||||
|
"content"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "cjwyett",
|
||||||
|
"name": "Cyrus Wyett",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/34195737?v=4",
|
||||||
|
"profile": "https://github.com/cjwyett",
|
||||||
|
"contributions": [
|
||||||
|
"content"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "cadolphs",
|
||||||
|
"name": "cadolphs",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/13894820?v=4",
|
||||||
|
"profile": "https://github.com/cadolphs",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "hpwxf",
|
||||||
|
"name": "Pascal H.",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/26146722?v=4",
|
||||||
|
"profile": "https://www.haveneer.com",
|
||||||
|
"contributions": [
|
||||||
|
"content"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "chapeupreto",
|
||||||
|
"name": "Rod Elias",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/834048?v=4",
|
||||||
|
"profile": "https://twitter.com/chapeupreto",
|
||||||
|
"contributions": [
|
||||||
|
"content"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "blerchy",
|
||||||
|
"name": "Matt Lebl",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/2555355?v=4",
|
||||||
|
"profile": "https://github.com/blerchy",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "flakolefluk",
|
||||||
|
"name": "Ignacio Le Fluk",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/11986564?v=4",
|
||||||
|
"profile": "http://flakolefluk.dev",
|
||||||
|
"contributions": [
|
||||||
|
"content"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "tlyu",
|
||||||
|
"name": "Taylor Yu",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/431873?v=4",
|
||||||
|
"profile": "https://github.com/tlyu",
|
||||||
|
"contributions": [
|
||||||
|
"code",
|
||||||
|
"content"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "Zerotask",
|
||||||
|
"name": "Patrick Hintermayer",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/20150243?v=4",
|
||||||
|
"profile": "https://zerotask.github.io",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "arthas168",
|
||||||
|
"name": "Pete Pavlovski",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/32264020?v=4",
|
||||||
|
"profile": "https://petkopavlovski.com/",
|
||||||
|
"contributions": [
|
||||||
|
"content"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "k12ish",
|
||||||
|
"name": "k12ish",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/45272873?v=4",
|
||||||
|
"profile": "https://github.com/k12ish",
|
||||||
|
"contributions": [
|
||||||
|
"content"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "hongshaoyang",
|
||||||
|
"name": "Shao Yang Hong",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/19281800?v=4",
|
||||||
|
"profile": "https://github.com/hongshaoyang",
|
||||||
|
"contributions": [
|
||||||
|
"content"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "bmacer",
|
||||||
|
"name": "Brandon Macer",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/13931806?v=4",
|
||||||
|
"profile": "https://github.com/bmacer",
|
||||||
|
"contributions": [
|
||||||
|
"content"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "stoiandan",
|
||||||
|
"name": "Stoian Dan",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/10388612?v=4",
|
||||||
|
"profile": "https://github.com/stoiandan",
|
||||||
|
"contributions": [
|
||||||
|
"content"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "PiDelport",
|
||||||
|
"name": "Pi Delport",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/630271?v=4",
|
||||||
|
"profile": "https://about.me/pjdelport",
|
||||||
|
"contributions": [
|
||||||
|
"content"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "sateeshkumarb",
|
||||||
|
"name": "Sateesh ",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/429263?v=4",
|
||||||
|
"profile": "https://github.com/sateeshkumarb",
|
||||||
|
"contributions": [
|
||||||
|
"code",
|
||||||
|
"content"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "kayuapi",
|
||||||
|
"name": "ZC",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/10304328?v=4",
|
||||||
|
"profile": "https://github.com/kayuapi",
|
||||||
|
"contributions": [
|
||||||
|
"content"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "hyperparabolic",
|
||||||
|
"name": "hyperparabolic",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/12348474?v=4",
|
||||||
|
"profile": "https://github.com/hyperparabolic",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "kolbma",
|
||||||
|
"name": "arlecchino",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/5228369?v=4",
|
||||||
|
"profile": "https://www.net4visions.at",
|
||||||
|
"contributions": [
|
||||||
|
"doc"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "jazzplato",
|
||||||
|
"name": "Richthofen",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/7576730?v=4",
|
||||||
|
"profile": "https://richthofen.io/",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "cseltol",
|
||||||
|
"name": "Ivan Nerazumov",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/64264529?v=4",
|
||||||
|
"profile": "https://github.com/cseltol",
|
||||||
|
"contributions": [
|
||||||
|
"doc"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"contributorsPerLine": 8,
|
"contributorsPerLine": 8,
|
||||||
|
|
45
CHANGELOG.md
45
CHANGELOG.md
|
@ -1,3 +1,48 @@
|
||||||
|
<a name="4.4.0"></a>
|
||||||
|
## 4.4.0 (2021-04-24)
|
||||||
|
|
||||||
|
|
||||||
|
#### Bug Fixes
|
||||||
|
|
||||||
|
* Fix spelling error in main.rs ([91ee27f2](https://github.com/rust-lang/rustlings/commit/91ee27f22bd3797a9db57e5fd430801c170c5db8))
|
||||||
|
* typo in default out text ([644c49f1](https://github.com/rust-lang/rustlings/commit/644c49f1e04cbb24e95872b3a52b07d692ae3bc8))
|
||||||
|
* **collections:** Naming exercises for vectors and hashmap ([bef39b12](https://github.com/rust-lang/rustlings/commit/bef39b125961310b34b34871e480a82e82af4678))
|
||||||
|
* **from_str:**
|
||||||
|
* Correct typos ([5f7c89f8](https://github.com/rust-lang/rustlings/commit/5f7c89f85db1f33da01911eaa479c3a2d4721678))
|
||||||
|
* test for error instead of unwrap/should_panic ([15e71535](https://github.com/rust-lang/rustlings/commit/15e71535f37cfaed36e22eb778728d186e2104ab))
|
||||||
|
* use trait objects for from_str ([c3e7b831](https://github.com/rust-lang/rustlings/commit/c3e7b831786c9172ed8bd5d150f3c432f242fba9))
|
||||||
|
* **functions3:** improve function argument type (#687) ([a6509cc4](https://github.com/rust-lang/rustlings/commit/a6509cc4d545d8825f01ddf7ee37823b372154dd))
|
||||||
|
* **hashmap2:** Update incorrect assertion (#660) ([72aaa15e](https://github.com/rust-lang/rustlings/commit/72aaa15e6ab4b72b3422f1c6356396e20a2a2bb8))
|
||||||
|
* **info:** Fix typo (#635) ([cddc1e86](https://github.com/rust-lang/rustlings/commit/cddc1e86e7ec744ee644cc774a4887b1a0ded3e8))
|
||||||
|
* **iterators2:** Moved errors out of tests. ([baf4ba17](https://github.com/rust-lang/rustlings/commit/baf4ba175ba6eb92989e3dd54ecbec4bedc9a863), closes [#359](https://github.com/rust-lang/rustlings/issues/359))
|
||||||
|
* **iterators3:** Enabled iterators3.rs to run without commented out tests. ([c6712dfc](https://github.com/rust-lang/rustlings/commit/c6712dfccd1a093e590ad22bbc4f49edc417dac0))
|
||||||
|
* **main:** Let find_exercise work with borrows ([347f30bd](https://github.com/rust-lang/rustlings/commit/347f30bd867343c5ace1097e085a1f7e356553f7))
|
||||||
|
* **move_semantics4:**
|
||||||
|
* Remove redundant "instead" (#640) ([cc266d7d](https://github.com/rust-lang/rustlings/commit/cc266d7d80b91e79df3f61984f231b7f1587218e))
|
||||||
|
* Small readbility improvement (#617) ([10965920](https://github.com/rust-lang/rustlings/commit/10965920fbdf8a1efc85bed869e55a1787006404))
|
||||||
|
* **option2:** Rename uninformative variables (#675) ([b4de6594](https://github.com/rust-lang/rustlings/commit/b4de6594380636817d13c2677ec6f472a964cf43))
|
||||||
|
* **quiz3:** Force an answer to Q2 (#672) ([0d894e6f](https://github.com/rust-lang/rustlings/commit/0d894e6ff739943901e1ae8c904582e5c2f843bd))
|
||||||
|
* **structs:** Add 5.3 to structs/README (#652) ([6bd791f2](https://github.com/rust-lang/rustlings/commit/6bd791f2f44aa7f0ad926df767f6b1fa8f12a9a9))
|
||||||
|
* **structs2:** correct grammar in hint (#663) ([ebdb66c7](https://github.com/rust-lang/rustlings/commit/ebdb66c7bfb6d687a14cc511a559a222e6fc5de4))
|
||||||
|
* **structs3:**
|
||||||
|
* reword heading comment (#664) ([9f3e8c2d](https://github.com/rust-lang/rustlings/commit/9f3e8c2dde645e5264c2d2200e68842b5f47bfa3))
|
||||||
|
* add check to prevent naive implementation of is_international ([05a753fe](https://github.com/rust-lang/rustlings/commit/05a753fe6333d36dbee5f68c21dec04eacdc75df))
|
||||||
|
* **threads1:** line number correction ([7857b0a6](https://github.com/rust-lang/rustlings/commit/7857b0a689b0847f48d8c14cbd1865e3b812d5ca))
|
||||||
|
* **try_from_into:** use trait objects ([2e93a588](https://github.com/rust-lang/rustlings/commit/2e93a588e0abe8badb7eafafb9e7d073c2be5df8))
|
||||||
|
|
||||||
|
#### Features
|
||||||
|
|
||||||
|
* Replace clap with argh ([7928122f](https://github.com/rust-lang/rustlings/commit/7928122fcef9ca7834d988b1ec8ca0687478beeb))
|
||||||
|
* Replace emojis when NO_EMOJI env variable present ([8d62a996](https://github.com/rust-lang/rustlings/commit/8d62a9963708dbecd9312e8bcc4b47049c72d155))
|
||||||
|
* Added iterators5.rs exercise. ([b29ea17e](https://github.com/rust-lang/rustlings/commit/b29ea17ea94d1862114af2cf5ced0e09c197dc35))
|
||||||
|
* **arc1:** Add more details to description and hint (#710) ([81be4044](https://github.com/rust-lang/rustlings/commit/81be40448777fa338ebced3b0bfc1b32d6370313))
|
||||||
|
* **cli:** Improve the list command with options, and then some ([8bbe4ff1](https://github.com/rust-lang/rustlings/commit/8bbe4ff1385c5c169c90cd3ff9253f9a91daaf8e))
|
||||||
|
* **list:**
|
||||||
|
* updated progress percentage ([1c6f7e4b](https://github.com/rust-lang/rustlings/commit/1c6f7e4b7b9b3bd36f4da2bb2b69c549cc8bd913))
|
||||||
|
* added progress info ([c0e3daac](https://github.com/rust-lang/rustlings/commit/c0e3daacaf6850811df5bc57fa43e0f249d5cfa4))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="4.3.0"></a>
|
<a name="4.3.0"></a>
|
||||||
## 4.3.0 (2020-12-29)
|
## 4.3.0 (2020-12-29)
|
||||||
|
|
||||||
|
|
|
@ -26,12 +26,12 @@ isn't really that complicated since the bulk of the work is done by `rustc`.
|
||||||
<a name="addex"></a>
|
<a name="addex"></a>
|
||||||
### Adding an exercise
|
### Adding an exercise
|
||||||
|
|
||||||
First step is to add the exercise! Call it `exercises/yourTopic/yourTopicN.rs`, make sure to
|
The first step is to add the exercise! Name the file `exercises/yourTopic/yourTopicN.rs`, make sure to
|
||||||
put in some helpful links, and link to sections of the book in `exercises/yourTopic/README.md`.
|
put in some helpful links, and link to sections of the book in `exercises/yourTopic/README.md`.
|
||||||
|
|
||||||
Next you want to make sure it runs when using `rustlings`. All exercises are stored in `info.toml`, under the `exercises` array. They're ordered by the order they're ran when using `rustlings verify`.
|
Next make sure it runs with `rustlings`. The exercise metadata is stored in `info.toml`, under the `exercises` array. The order of the `exercises` array determines the order the exercises are run by `rustlings verify`.
|
||||||
|
|
||||||
You want to make sure where in the file you add your exercise. If you're not sure, add it at the bottom and ask in your pull request. To add an exercise, edit the file like this:
|
Add the metadata for your exercise in the correct order in the `exercises` array. If you are unsure of the correct ordering, add it at the bottom and ask in your pull request. The exercise metadata should contain the following:
|
||||||
```diff
|
```diff
|
||||||
...
|
...
|
||||||
+ [[exercises]]
|
+ [[exercises]]
|
||||||
|
|
549
Cargo.lock
generated
549
Cargo.lock
generated
|
@ -2,22 +2,42 @@
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aho-corasick"
|
name = "aho-corasick"
|
||||||
version = "0.7.3"
|
version = "0.7.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e6f484ae0c99fec2e858eb6134949117399f222608d84cadb3f58c1f97c2364c"
|
checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ansi_term"
|
name = "argh"
|
||||||
version = "0.11.0"
|
version = "0.1.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
|
checksum = "91792f088f87cdc7a2cfb1d617fa5ea18d7f1dc22ef0e1b5f82f3157cdc522be"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"winapi 0.3.8",
|
"argh_derive",
|
||||||
|
"argh_shared",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "argh_derive"
|
||||||
|
version = "0.1.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c4eb0c0c120ad477412dc95a4ce31e38f2113e46bd13511253f79196ca68b067"
|
||||||
|
dependencies = [
|
||||||
|
"argh_shared",
|
||||||
|
"heck",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "argh_shared"
|
||||||
|
version = "0.1.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "781f336cc9826dbaddb9754cb5db61e64cab4f69668bd19dcc4a0394a86f4cb1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "assert_cmd"
|
name = "assert_cmd"
|
||||||
version = "0.11.1"
|
version = "0.11.1"
|
||||||
|
@ -32,67 +52,49 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "atty"
|
name = "atty"
|
||||||
version = "0.2.11"
|
version = "0.2.14"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652"
|
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"hermit-abi",
|
||||||
"libc",
|
"libc",
|
||||||
"termion",
|
"winapi 0.3.9",
|
||||||
"winapi 0.3.8",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
version = "0.1.4"
|
version = "1.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0e49efa51329a5fd37e7c79db4621af617cd4e3e5bc224939808d076077077bf"
|
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "1.0.4"
|
version = "1.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
|
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
version = "0.1.9"
|
version = "0.1.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b486ce3ccf7ffd79fdeb678eac06a9e6c09fc88d33836340becb8fffe87c5e33"
|
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "cfg-if"
|
||||||
version = "2.33.0"
|
version = "1.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9"
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
dependencies = [
|
|
||||||
"ansi_term",
|
|
||||||
"atty",
|
|
||||||
"bitflags",
|
|
||||||
"strsim",
|
|
||||||
"textwrap",
|
|
||||||
"unicode-width",
|
|
||||||
"vec_map",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clicolors-control"
|
name = "clicolors-control"
|
||||||
version = "1.0.0"
|
version = "1.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "73abfd4c73d003a674ce5d2933fca6ce6c42480ea84a5ffe0a2dc39ed56300f9"
|
checksum = "90082ee5dcdd64dc4e9e0d37fbf3ee325419e39c0092191e0393df65518f741e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atty",
|
"atty",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"libc",
|
"libc",
|
||||||
"winapi 0.3.8",
|
"winapi 0.3.9",
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cloudabi"
|
|
||||||
version = "0.0.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -110,23 +112,22 @@ dependencies = [
|
||||||
"regex",
|
"regex",
|
||||||
"termios",
|
"termios",
|
||||||
"unicode-width",
|
"unicode-width",
|
||||||
"winapi 0.3.8",
|
"winapi 0.3.9",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "console"
|
name = "console"
|
||||||
version = "0.8.0"
|
version = "0.14.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b147390a412132d75d10dd3b7b175a69cf5fd95032f7503c7091b8831ba10242"
|
checksum = "3993e6445baa160675931ec041a5e03ca84b9c6e32a056150d3aa2bdda0a1f45"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clicolors-control",
|
|
||||||
"encode_unicode",
|
"encode_unicode",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"libc",
|
"libc",
|
||||||
"regex",
|
"regex",
|
||||||
"termios",
|
"terminal_size",
|
||||||
"unicode-width",
|
"unicode-width",
|
||||||
"winapi 0.3.8",
|
"winapi 0.3.9",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -137,9 +138,9 @@ checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "encode_unicode"
|
name = "encode_unicode"
|
||||||
version = "0.3.5"
|
version = "0.3.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "90b2c9496c001e8cb61827acdefad780795c42264c137744cae6f7d9e3450abd"
|
checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "escargot"
|
name = "escargot"
|
||||||
|
@ -155,20 +156,21 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "filetime"
|
name = "filetime"
|
||||||
version = "0.2.5"
|
version = "0.2.14"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2f8c63033fcba1f51ef744505b3cad42510432b904c062afa67ad7ece008429d"
|
checksum = "1d34cfa13a63ae058bfa601fe9e313bbdb3746427c1459185464ce0fcf62e1e8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if 1.0.0",
|
||||||
"libc",
|
"libc",
|
||||||
"redox_syscall",
|
"redox_syscall",
|
||||||
|
"winapi 0.3.9",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "float-cmp"
|
name = "float-cmp"
|
||||||
version = "0.4.0"
|
version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "134a8fa843d80a51a5b77d36d42bc2def9edcb0262c914861d08129fd1926600"
|
checksum = "e1267f4ac4f343772758f7b1bdcbe767c218bbab93bb432acbf5162bbf85a6c4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"num-traits",
|
"num-traits",
|
||||||
]
|
]
|
||||||
|
@ -192,12 +194,6 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "fuchsia-cprng"
|
|
||||||
version = "0.1.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fuchsia-zircon"
|
name = "fuchsia-zircon"
|
||||||
version = "0.3.3"
|
version = "0.3.3"
|
||||||
|
@ -220,13 +216,31 @@ version = "0.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
|
checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "heck"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "87cbf45460356b7deeb5e3415b5563308c0a9b057c85e12b06ad551f98d0a6ac"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-segmentation",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hermit-abi"
|
||||||
|
version = "0.1.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indicatif"
|
name = "indicatif"
|
||||||
version = "0.10.3"
|
version = "0.10.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "40ecd1e2ee08e6c255ce890f5a99d17000850e664e7acf119fb03b25b0575bfe"
|
checksum = "40ecd1e2ee08e6c255ce890f5a99d17000850e664e7acf119fb03b25b0575bfe"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"console 0.8.0",
|
"console 0.14.1",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"number_prefix",
|
"number_prefix",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
|
@ -235,9 +249,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "inotify"
|
name = "inotify"
|
||||||
version = "0.7.0"
|
version = "0.7.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "24e40d6fd5d64e2082e0c796495c8ef5ad667a96d03e5aaa0becfd9d47bcbfb8"
|
checksum = "4816c66d2c8ae673df83366c18341538f234a26d65a9ecea5c348b453ac1d02f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"inotify-sys",
|
"inotify-sys",
|
||||||
|
@ -246,28 +260,36 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "inotify-sys"
|
name = "inotify-sys"
|
||||||
version = "0.1.3"
|
version = "0.1.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e74a1aa87c59aeff6ef2cc2fa62d41bc43f54952f55652656b18a02fd5e356c0"
|
checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "instant"
|
||||||
|
version = "0.1.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 1.0.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iovec"
|
name = "iovec"
|
||||||
version = "0.1.2"
|
version = "0.1.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08"
|
checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"winapi 0.2.8",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
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 = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f"
|
checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kernel32-sys"
|
name = "kernel32-sys"
|
||||||
|
@ -281,52 +303,53 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lazy_static"
|
name = "lazy_static"
|
||||||
version = "1.3.0"
|
version = "1.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14"
|
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lazycell"
|
name = "lazycell"
|
||||||
version = "1.2.1"
|
version = "1.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
|
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.58"
|
version = "0.2.93"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6281b86796ba5e4366000be6e9e18bf35580adf9e63fbe2294aadb587613a319"
|
checksum = "9385f66bf6105b241aa65a61cb923ef20efc665cb9f9bb50ac2f0c4b7f378d41"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lock_api"
|
name = "lock_api"
|
||||||
version = "0.2.0"
|
version = "0.4.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ed946d4529956a20f2d63ebe1b69996d5a2137c91913fe3ebbeff957f5bca7ff"
|
checksum = "5a3c91c24eae6777794bb1997ad98bbb87daf92890acab859f7eaa4320333176"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"scopeguard",
|
"scopeguard",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "log"
|
name = "log"
|
||||||
version = "0.4.6"
|
version = "0.4.14"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6"
|
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if 1.0.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "2.2.0"
|
version = "2.3.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2efc7bc57c883d4a4d6e3246905283d8dae951bb3bd32f49d6ef297f546e1c39"
|
checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mio"
|
name = "mio"
|
||||||
version = "0.6.19"
|
version = "0.6.23"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "83f51996a3ed004ef184e16818edc51fadffe8e7ca68be67f9dee67d84d0ff23"
|
checksum = "4afd66f5b91bf2a3bc13fad0e21caedac168ca4c707504e75585648ae80e4cc4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"cfg-if 0.1.10",
|
||||||
"fuchsia-zircon",
|
"fuchsia-zircon",
|
||||||
"fuchsia-zircon-sys",
|
"fuchsia-zircon-sys",
|
||||||
"iovec",
|
"iovec",
|
||||||
|
@ -341,9 +364,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mio-extras"
|
name = "mio-extras"
|
||||||
version = "2.0.5"
|
version = "2.0.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "46e73a04c2fa6250b8d802134d56d554a9ec2922bf977777c805ea5def61ce40"
|
checksum = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lazycell",
|
"lazycell",
|
||||||
"log",
|
"log",
|
||||||
|
@ -353,9 +376,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "miow"
|
name = "miow"
|
||||||
version = "0.2.1"
|
version = "0.2.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
|
checksum = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"kernel32-sys",
|
"kernel32-sys",
|
||||||
"net2",
|
"net2",
|
||||||
|
@ -365,26 +388,26 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "net2"
|
name = "net2"
|
||||||
version = "0.2.33"
|
version = "0.2.37"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"
|
checksum = "391630d12b68002ae1e25e8f974306474966550ad82dac6886fb8910c19568ae"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if 0.1.10",
|
||||||
"libc",
|
"libc",
|
||||||
"winapi 0.3.8",
|
"winapi 0.3.9",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "normalize-line-endings"
|
name = "normalize-line-endings"
|
||||||
version = "0.2.2"
|
version = "0.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2e0a1a39eab95caf4f5556da9289b9e68f0aafac901b2ce80daaf020d3b733a8"
|
checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "notify"
|
name = "notify"
|
||||||
version = "4.0.15"
|
version = "4.0.16"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "80ae4a7688d1fab81c5bf19c64fc8db920be8d519ce6336ed4e7efe024724dbd"
|
checksum = "2599080e87c9bd051ddb11b10074f4da7b1223298df65d4c2ec5bcf309af1533"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"filetime",
|
"filetime",
|
||||||
|
@ -395,14 +418,14 @@ dependencies = [
|
||||||
"mio",
|
"mio",
|
||||||
"mio-extras",
|
"mio-extras",
|
||||||
"walkdir",
|
"walkdir",
|
||||||
"winapi 0.3.8",
|
"winapi 0.3.9",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-traits"
|
name = "num-traits"
|
||||||
version = "0.2.8"
|
version = "0.2.14"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32"
|
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
]
|
]
|
||||||
|
@ -416,44 +439,36 @@ dependencies = [
|
||||||
"num-traits",
|
"num-traits",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "numtoa"
|
|
||||||
version = "0.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parking_lot"
|
name = "parking_lot"
|
||||||
version = "0.8.0"
|
version = "0.11.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fa7767817701cce701d5585b9c4db3cdd02086398322c1d7e8bf5094a96a2ce7"
|
checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"instant",
|
||||||
"lock_api",
|
"lock_api",
|
||||||
"parking_lot_core",
|
"parking_lot_core",
|
||||||
"rustc_version",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parking_lot_core"
|
name = "parking_lot_core"
|
||||||
version = "0.5.0"
|
version = "0.8.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cb88cb1cb3790baa6776844f968fea3be44956cf184fa1be5a03341f5491278c"
|
checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if 1.0.0",
|
||||||
"cloudabi",
|
"instant",
|
||||||
"libc",
|
"libc",
|
||||||
"rand",
|
|
||||||
"redox_syscall",
|
"redox_syscall",
|
||||||
"rustc_version",
|
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"winapi 0.3.8",
|
"winapi 0.3.9",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "predicates"
|
name = "predicates"
|
||||||
version = "1.0.1"
|
version = "1.0.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "53e09015b0d3f5a0ec2d4428f7559bb7b3fff341b4e159fedd1d57fac8b939ff"
|
checksum = "eeb433456c1a57cc93554dea3ce40b4c19c4057e41c55d4a0f3d84ea71c325aa"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"difference",
|
"difference",
|
||||||
"float-cmp",
|
"float-cmp",
|
||||||
|
@ -464,15 +479,15 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "predicates-core"
|
name = "predicates-core"
|
||||||
version = "1.0.0"
|
version = "1.0.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "06075c3a3e92559ff8929e7a280684489ea27fe44805174c3ebd9328dcb37178"
|
checksum = "57e35a3326b75e49aa85f5dc6ec15b41108cf5aee58eabb1f274dd18b73c2451"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "predicates-tree"
|
name = "predicates-tree"
|
||||||
version = "1.0.0"
|
version = "1.0.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8e63c4859013b38a76eca2414c64911fba30def9e3202ac461a2d22831220124"
|
checksum = "15f553275e5721409451eb85e15fd9a860a6e5ab4496eb215987502b5f5391f2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"predicates-core",
|
"predicates-core",
|
||||||
"treeline",
|
"treeline",
|
||||||
|
@ -480,189 +495,54 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "0.4.30"
|
version = "1.0.26"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
|
checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-xid",
|
"unicode-xid",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "0.6.12"
|
version = "1.0.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "faf4799c5d274f3868a4aae320a0a182cbd2baee377b378f080e16a23e9d80db"
|
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand"
|
|
||||||
version = "0.6.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
|
|
||||||
dependencies = [
|
|
||||||
"autocfg",
|
|
||||||
"libc",
|
|
||||||
"rand_chacha",
|
|
||||||
"rand_core 0.4.0",
|
|
||||||
"rand_hc",
|
|
||||||
"rand_isaac",
|
|
||||||
"rand_jitter",
|
|
||||||
"rand_os",
|
|
||||||
"rand_pcg",
|
|
||||||
"rand_xorshift",
|
|
||||||
"winapi 0.3.8",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand_chacha"
|
|
||||||
version = "0.1.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
|
|
||||||
dependencies = [
|
|
||||||
"autocfg",
|
|
||||||
"rand_core 0.3.1",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand_core"
|
|
||||||
version = "0.3.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
|
|
||||||
dependencies = [
|
|
||||||
"rand_core 0.4.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand_core"
|
|
||||||
version = "0.4.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand_hc"
|
|
||||||
version = "0.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4"
|
|
||||||
dependencies = [
|
|
||||||
"rand_core 0.3.1",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand_isaac"
|
|
||||||
version = "0.1.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08"
|
|
||||||
dependencies = [
|
|
||||||
"rand_core 0.3.1",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand_jitter"
|
|
||||||
version = "0.1.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"rand_core 0.4.0",
|
|
||||||
"winapi 0.3.8",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand_os"
|
|
||||||
version = "0.1.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071"
|
|
||||||
dependencies = [
|
|
||||||
"cloudabi",
|
|
||||||
"fuchsia-cprng",
|
|
||||||
"libc",
|
|
||||||
"rand_core 0.4.0",
|
|
||||||
"rdrand",
|
|
||||||
"winapi 0.3.8",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand_pcg"
|
|
||||||
version = "0.1.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44"
|
|
||||||
dependencies = [
|
|
||||||
"autocfg",
|
|
||||||
"rand_core 0.4.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand_xorshift"
|
|
||||||
version = "0.1.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
|
|
||||||
dependencies = [
|
|
||||||
"rand_core 0.3.1",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rdrand"
|
|
||||||
version = "0.4.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
|
|
||||||
dependencies = [
|
|
||||||
"rand_core 0.3.1",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "redox_syscall"
|
name = "redox_syscall"
|
||||||
version = "0.1.54"
|
version = "0.2.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "12229c14a0f65c4f1cb046a3b52047cdd9da1f4b30f8a39c5063c8bae515e252"
|
checksum = "8270314b5ccceb518e7e578952f0b72b88222d02e8f77f5ecf7abbb673539041"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "redox_termios"
|
|
||||||
version = "0.1.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"redox_syscall",
|
"bitflags",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "1.1.6"
|
version = "1.4.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8f0a0bcab2fd7d1d7c54fa9eae6f43eddeb9ce2e7352f8518a814a4f65d60c58"
|
checksum = "2a26af418b574bd56588335b3a3659a65725d4e636eb1016c2f9e3b38c7cc759"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
"memchr",
|
"memchr",
|
||||||
"regex-syntax",
|
"regex-syntax",
|
||||||
"thread_local",
|
|
||||||
"utf8-ranges",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex-syntax"
|
name = "regex-syntax"
|
||||||
version = "0.6.6"
|
version = "0.6.23"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dcfd8681eebe297b81d98498869d4aae052137651ad7b96822f09ceb690d0a96"
|
checksum = "24d5f089152e60f62d28b835fbff2cd2e8dc0baf1ac13343bef92ab7eed84548"
|
||||||
dependencies = [
|
|
||||||
"ucd-util",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rustc_version"
|
|
||||||
version = "0.2.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
|
||||||
dependencies = [
|
|
||||||
"semver",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustlings"
|
name = "rustlings"
|
||||||
version = "4.3.0"
|
version = "4.4.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"argh",
|
||||||
"assert_cmd",
|
"assert_cmd",
|
||||||
"clap",
|
|
||||||
"console 0.7.7",
|
"console 0.7.7",
|
||||||
"glob",
|
"glob",
|
||||||
"indicatif",
|
"indicatif",
|
||||||
|
@ -675,54 +555,39 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ryu"
|
name = "ryu"
|
||||||
version = "0.2.8"
|
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 = "b96a9549dc8d48f2c283938303c4b5a77aa29bfbc5b54b084fb1630408899a8f"
|
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "same-file"
|
name = "same-file"
|
||||||
version = "1.0.4"
|
version = "1.0.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8f20c4be53a8a1ff4c1f1b2bd14570d2f634628709752f0702ecdd2b3f9a5267"
|
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"winapi-util",
|
"winapi-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scopeguard"
|
name = "scopeguard"
|
||||||
version = "1.0.0"
|
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 = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d"
|
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "semver"
|
|
||||||
version = "0.9.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
|
|
||||||
dependencies = [
|
|
||||||
"semver-parser",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "semver-parser"
|
|
||||||
version = "0.7.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.92"
|
version = "1.0.125"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "32746bf0f26eab52f06af0d0aa1984f641341d06d8d673c693871da2d188c9be"
|
checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.92"
|
version = "1.0.125"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "46a3223d0c9ba936b61c0d2e3e559e3217dbfb8d65d06d26e8b3c25de38bae3e"
|
checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -731,9 +596,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.39"
|
version = "1.0.64"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5a23aa71d4a4d43fdbfaac00eff68ba8a06a51759a89ac3304323e800c4dd40d"
|
checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itoa",
|
"itoa",
|
||||||
"ryu",
|
"ryu",
|
||||||
|
@ -742,27 +607,21 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "slab"
|
name = "slab"
|
||||||
version = "0.4.2"
|
version = "0.4.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
|
checksum = "f173ac3d1a7e3b28003f40de0b5ce7fe2710f9b9dc3fc38664cebee46b3b6527"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smallvec"
|
name = "smallvec"
|
||||||
version = "0.6.9"
|
version = "1.6.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c4488ae950c49d403731982257768f48fada354a5203fe81f9bb6f43ca9002be"
|
checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "strsim"
|
|
||||||
version = "0.8.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "0.15.34"
|
version = "1.0.70"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a1393e4a97a19c01e900df2aec855a29f71cf02c402e2f443b8d2747c25c5dbe"
|
checksum = "b9505f307c872bab8eb46f77ae357c8eba1fdacead58ee5a850116b1d7f82883"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -770,44 +629,24 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "termion"
|
name = "terminal_size"
|
||||||
version = "1.5.2"
|
version = "0.1.16"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dde0593aeb8d47accea5392b39350015b5eccb12c0d98044d856983d89548dea"
|
checksum = "86ca8ced750734db02076f44132d802af0b33b09942331f4459dde8636fd2406"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"numtoa",
|
"winapi 0.3.9",
|
||||||
"redox_syscall",
|
|
||||||
"redox_termios",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "termios"
|
name = "termios"
|
||||||
version = "0.3.1"
|
version = "0.3.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "72b620c5ea021d75a735c943269bb07d30c9b77d6ac6b236bc8b5c496ef05625"
|
checksum = "411c5bf740737c7918b8b1fe232dca4dc9f8e754b8ad5e20966814001ed0ac6b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "textwrap"
|
|
||||||
version = "0.11.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
|
|
||||||
dependencies = [
|
|
||||||
"unicode-width",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "thread_local"
|
|
||||||
version = "0.3.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
|
|
||||||
dependencies = [
|
|
||||||
"lazy_static",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml"
|
name = "toml"
|
||||||
version = "0.4.10"
|
version = "0.4.10"
|
||||||
|
@ -824,43 +663,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a7f741b240f1a48843f9b8e0444fb55fb2a4ff67293b50a9179dfd5ea67f8d41"
|
checksum = "a7f741b240f1a48843f9b8e0444fb55fb2a4ff67293b50a9179dfd5ea67f8d41"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ucd-util"
|
name = "unicode-segmentation"
|
||||||
version = "0.1.3"
|
version = "1.7.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86"
|
checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-width"
|
name = "unicode-width"
|
||||||
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 = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526"
|
checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-xid"
|
name = "unicode-xid"
|
||||||
version = "0.1.0"
|
version = "0.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "utf8-ranges"
|
|
||||||
version = "1.0.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "796f7e48bef87609f7ade7e06495a87d5cd06c7866e6a5cbfceffc558a243737"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "vec_map"
|
|
||||||
version = "0.8.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "walkdir"
|
name = "walkdir"
|
||||||
version = "2.2.7"
|
version = "2.3.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9d9d7ed3431229a144296213105a390676cc49c9b6a72bd19f3176c98e129fa1"
|
checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"same-file",
|
"same-file",
|
||||||
"winapi 0.3.8",
|
"winapi 0.3.9",
|
||||||
"winapi-util",
|
"winapi-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -872,9 +699,9 @@ checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi"
|
name = "winapi"
|
||||||
version = "0.3.8"
|
version = "0.3.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
|
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"winapi-i686-pc-windows-gnu",
|
"winapi-i686-pc-windows-gnu",
|
||||||
"winapi-x86_64-pc-windows-gnu",
|
"winapi-x86_64-pc-windows-gnu",
|
||||||
|
@ -894,11 +721,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi-util"
|
name = "winapi-util"
|
||||||
version = "0.1.2"
|
version = "0.1.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9"
|
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"winapi 0.3.8",
|
"winapi 0.3.9",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
[package]
|
[package]
|
||||||
name = "rustlings"
|
name = "rustlings"
|
||||||
version = "4.3.0"
|
version = "4.4.0"
|
||||||
authors = ["Marisa <mokou@posteo.de>", "Carol (Nichols || Goulding) <carol.nichols@gmail.com>"]
|
authors = ["Marisa <mokou@posteo.de>", "Carol (Nichols || Goulding) <carol.nichols@gmail.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = "2.32.0"
|
argh = "0.1.4"
|
||||||
indicatif = "0.10.3"
|
indicatif = "0.10.3"
|
||||||
console = "0.7.7"
|
console = "0.7.7"
|
||||||
notify = "4.0.15"
|
notify = "4.0.15"
|
||||||
|
|
264
README.md
264
README.md
|
@ -1,263 +1,3 @@
|
||||||
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
|
# rustlings
|
||||||
[![All Contributors](https://img.shields.io/badge/all_contributors-73-orange.svg?style=flat-square)](#contributors-)
|
|
||||||
<!-- ALL-CONTRIBUTORS-BADGE:END -->
|
|
||||||
|
|
||||||
# rustlings 🦀❤️
|
My solutions to rustlings excercises
|
||||||
|
|
||||||
Greetings and welcome to `rustlings`. This project contains small exercises to get you used to reading and writing Rust code. This includes reading and responding to compiler messages!
|
|
||||||
|
|
||||||
_...looking for the old, web-based version of Rustlings? Try [here](https://github.com/rust-lang/rustlings/tree/rustlings-1)_
|
|
||||||
|
|
||||||
Alternatively, for a first-time Rust learner, there are several other resources:
|
|
||||||
|
|
||||||
- [The Book](https://doc.rust-lang.org/book/index.html) - The most comprehensive resource for learning Rust, but a bit theoretical sometimes. You will be using this along with Rustlings!
|
|
||||||
- [Rust By Example](https://doc.rust-lang.org/rust-by-example/index.html) - Learn Rust by solving little exercises! It's almost like `rustlings`, but online
|
|
||||||
|
|
||||||
## Getting Started
|
|
||||||
|
|
||||||
_Note: If you're on MacOS, make sure you've installed Xcode and its developer tools by typing `xcode-select --install`._
|
|
||||||
|
|
||||||
You will need to have Rust installed. You can get it by visiting https://rustup.rs. This'll also install Cargo, Rust's package/project manager.
|
|
||||||
|
|
||||||
## MacOS/Linux
|
|
||||||
|
|
||||||
Just run:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -L https://git.io/rustlings | bash
|
|
||||||
# Or if you want it to be installed to a different path:
|
|
||||||
curl -L https://git.io/rustlings | bash -s mypath/
|
|
||||||
```
|
|
||||||
|
|
||||||
This will install Rustlings and give you access to the `rustlings` command. Run it to get started!
|
|
||||||
|
|
||||||
## Windows
|
|
||||||
|
|
||||||
In PowerShell, set `ExecutionPolicy` to `RemoteSigned`:
|
|
||||||
|
|
||||||
```ps
|
|
||||||
Set-ExecutionPolicy RemoteSigned
|
|
||||||
```
|
|
||||||
|
|
||||||
Then, you can run:
|
|
||||||
|
|
||||||
```ps
|
|
||||||
Start-BitsTransfer -Source https://git.io/rustlings-win -Destination $env:TMP/install_rustlings.ps1; Unblock-File $env:TMP/install_rustlings.ps1; Invoke-Expression $env:TMP/install_rustlings.ps1
|
|
||||||
```
|
|
||||||
|
|
||||||
To install Rustlings. Same as on MacOS/Linux, you will have access to the `rustlings` command after it.
|
|
||||||
|
|
||||||
When you get a permission denied message then you have to exclude the directory where you placed the rustlings in your virus-scanner
|
|
||||||
|
|
||||||
## Browser:
|
|
||||||
|
|
||||||
[Run on Repl.it](https://repl.it/github/rust-lang/rustlings)
|
|
||||||
|
|
||||||
[Open in Gitpod](https://gitpod.io/#https://github.com/rust-lang/rustlings)
|
|
||||||
|
|
||||||
## Manually
|
|
||||||
|
|
||||||
Basically: Clone the repository, checkout to the latest tag, run `cargo install`.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git clone https://github.com/rust-lang/rustlings
|
|
||||||
cd rustlings
|
|
||||||
git checkout tags/4.3.0 # or whatever the latest version is (find out at https://github.com/rust-lang/rustlings/releases/latest)
|
|
||||||
cargo install --force --path .
|
|
||||||
```
|
|
||||||
|
|
||||||
If there are installation errors, ensure that your toolchain is up to date. For the latest, run:
|
|
||||||
```bash
|
|
||||||
rustup update
|
|
||||||
```
|
|
||||||
|
|
||||||
Then, same as above, run `rustlings` to get started.
|
|
||||||
|
|
||||||
## Doing exercises
|
|
||||||
|
|
||||||
The exercises are sorted by topic and can be found in the subdirectory `rustlings/exercises/<topic>`. For every topic there is an additional README file with some resources to get you started on the topic. We really recommend that you have a look at them before you start.
|
|
||||||
|
|
||||||
The task is simple. Most exercises contain an error that keeps them from compiling, and it's up to you to fix it! Some exercises are also run as tests, but rustlings handles them all the same. To run the exercises in the recommended order, execute:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
rustlings watch
|
|
||||||
```
|
|
||||||
|
|
||||||
This will try to verify the completion of every exercise in a predetermined order (what we think is best for newcomers). It will also rerun automatically every time you change a file in the `exercises/` directory. If you want to only run it once, you can use:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
rustlings verify
|
|
||||||
```
|
|
||||||
|
|
||||||
This will do the same as watch, but it'll quit after running.
|
|
||||||
|
|
||||||
In case you want to go by your own order, or want to only verify a single exercise, you can run:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
rustlings run myExercise1
|
|
||||||
```
|
|
||||||
|
|
||||||
In case you get stuck, you can run the following command to get a hint for your
|
|
||||||
exercise:
|
|
||||||
|
|
||||||
``` bash
|
|
||||||
rustlings hint myExercise1
|
|
||||||
```
|
|
||||||
|
|
||||||
## Testing yourself
|
|
||||||
|
|
||||||
After every couple of sections, there will be a quiz that'll test your knowledge on a bunch of sections at once. These quizzes are found in `exercises/quizN.rs`.
|
|
||||||
|
|
||||||
## Continuing On
|
|
||||||
|
|
||||||
Once you've completed Rustlings, put your new knowledge to good use! Continue practicing your Rust skills by building your own projects, contributing to Rustlings, or finding other open-source projects to contribute to.
|
|
||||||
|
|
||||||
## Uninstalling Rustlings
|
|
||||||
|
|
||||||
If you want to remove Rustlings from your system, there's two steps. First, you'll need to remove the exercises folder that the install script created
|
|
||||||
for you:
|
|
||||||
|
|
||||||
``` bash
|
|
||||||
rm -rf rustlings # or your custom folder name, if you chose and or renamed it
|
|
||||||
```
|
|
||||||
|
|
||||||
Second, since Rustlings got installed via `cargo install`, it's only reasonable to assume that you can also remove it using Cargo, and
|
|
||||||
exactly that is the case. Run `cargo uninstall` to remove the `rustlings` binary:
|
|
||||||
|
|
||||||
``` bash
|
|
||||||
cargo uninstall rustlings
|
|
||||||
```
|
|
||||||
|
|
||||||
Now you should be done!
|
|
||||||
|
|
||||||
## Completion
|
|
||||||
|
|
||||||
Rustlings isn't done; there are a couple of sections that are very experimental and don't have proper documentation. These include:
|
|
||||||
|
|
||||||
- Errors (`exercises/errors/`)
|
|
||||||
- Option (`exercises/option/`)
|
|
||||||
- Result (`exercises/result/`)
|
|
||||||
- Move Semantics (could still be improved, `exercises/move_semantics/`)
|
|
||||||
|
|
||||||
Additionally, we could use exercises on a couple of topics:
|
|
||||||
|
|
||||||
- Structs
|
|
||||||
- Better ownership stuff
|
|
||||||
- `impl`
|
|
||||||
- ??? probably more
|
|
||||||
|
|
||||||
If you are interested in improving or adding new ones, please feel free to contribute! Read on for more information :)
|
|
||||||
|
|
||||||
## Contributing
|
|
||||||
|
|
||||||
See [CONTRIBUTING.md](./CONTRIBUTING.md).
|
|
||||||
|
|
||||||
## Contributors ✨
|
|
||||||
|
|
||||||
Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
|
|
||||||
|
|
||||||
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
|
|
||||||
<!-- prettier-ignore-start -->
|
|
||||||
<!-- markdownlint-disable -->
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td align="center"><a href="http://carol-nichols.com"><img src="https://avatars2.githubusercontent.com/u/193874?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Carol (Nichols || Goulding)</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=carols10cents" title="Code">💻</a> <a href="#content-carols10cents" title="Content">🖋</a></td>
|
|
||||||
<td align="center"><a href="https://twitter.com/QuietMisdreavus"><img src="https://avatars2.githubusercontent.com/u/5217170?v=4?s=100" width="100px;" alt=""/><br /><sub><b>QuietMisdreavus</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=QuietMisdreavus" title="Code">💻</a> <a href="#content-QuietMisdreavus" title="Content">🖋</a></td>
|
|
||||||
<td align="center"><a href="https://github.com/robertlugg"><img src="https://avatars0.githubusercontent.com/u/6054540?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Robert M Lugg</b></sub></a><br /><a href="#content-robertlugg" title="Content">🖋</a></td>
|
|
||||||
<td align="center"><a href="https://hynek.me/about/"><img src="https://avatars3.githubusercontent.com/u/41240?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Hynek Schlawack</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=hynek" title="Code">💻</a></td>
|
|
||||||
<td align="center"><a href="https://spacekookie.de"><img src="https://avatars0.githubusercontent.com/u/7669898?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Katharina Fey</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=spacekookie" title="Code">💻</a></td>
|
|
||||||
<td align="center"><a href="https://github.com/lukabavdaz"><img src="https://avatars0.githubusercontent.com/u/9624558?v=4?s=100" width="100px;" alt=""/><br /><sub><b>lukabavdaz</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=lukabavdaz" title="Code">💻</a> <a href="#content-lukabavdaz" title="Content">🖋</a></td>
|
|
||||||
<td align="center"><a href="http://vestera.as"><img src="https://avatars2.githubusercontent.com/u/4187449?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Erik Vesteraas</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=evestera" title="Code">💻</a></td>
|
|
||||||
<td align="center"><a href="https://github.com/Delet0r"><img src="https://avatars1.githubusercontent.com/u/23195618?v=4?s=100" width="100px;" alt=""/><br /><sub><b>delet0r</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=Delet0r" title="Code">💻</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td align="center"><a href="http://phinary.ca"><img src="https://avatars1.githubusercontent.com/u/10522375?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Shaun Bennett</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=shaunbennett" title="Code">💻</a></td>
|
|
||||||
<td align="center"><a href="https://github.com/abagshaw"><img src="https://avatars2.githubusercontent.com/u/8594541?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Andrew Bagshaw</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=abagshaw" title="Code">💻</a></td>
|
|
||||||
<td align="center"><a href="https://ai6ua.net/"><img src="https://avatars2.githubusercontent.com/u/175578?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Kyle Isom</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=kisom" title="Code">💻</a></td>
|
|
||||||
<td align="center"><a href="https://github.com/ColinPitrat"><img src="https://avatars3.githubusercontent.com/u/1541863?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Colin Pitrat</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=ColinPitrat" title="Code">💻</a></td>
|
|
||||||
<td align="center"><a href="https://zacanger.com"><img src="https://avatars3.githubusercontent.com/u/12520493?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Zac Anger</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=zacanger" title="Code">💻</a></td>
|
|
||||||
<td align="center"><a href="https://github.com/mgeier"><img src="https://avatars1.githubusercontent.com/u/705404?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Matthias Geier</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=mgeier" title="Code">💻</a></td>
|
|
||||||
<td align="center"><a href="https://github.com/cjpearce"><img src="https://avatars1.githubusercontent.com/u/3453268?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Chris Pearce</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=cjpearce" title="Code">💻</a></td>
|
|
||||||
<td align="center"><a href="https://yvan-sraka.github.io"><img src="https://avatars2.githubusercontent.com/u/705213?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Yvan Sraka</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=yvan-sraka" title="Code">💻</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td align="center"><a href="https://github.com/dendi239"><img src="https://avatars3.githubusercontent.com/u/16478650?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Denys Smirnov</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=dendi239" title="Code">💻</a></td>
|
|
||||||
<td align="center"><a href="https://github.com/eddyp"><img src="https://avatars2.githubusercontent.com/u/123772?v=4?s=100" width="100px;" alt=""/><br /><sub><b>eddyp</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=eddyp" title="Code">💻</a></td>
|
|
||||||
<td align="center"><a href="http://about.me/BrianKung"><img src="https://avatars1.githubusercontent.com/u/2836167?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Brian Kung</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=briankung" title="Code">💻</a> <a href="#content-briankung" title="Content">🖋</a></td>
|
|
||||||
<td align="center"><a href="https://rcousineau.gitlab.io"><img src="https://avatars3.githubusercontent.com/u/281039?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Russell</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=miller-time" title="Code">💻</a></td>
|
|
||||||
<td align="center"><a href="http://danwilhelm.com"><img src="https://avatars3.githubusercontent.com/u/6137185?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Dan Wilhelm</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=danwilhelm" title="Documentation">📖</a></td>
|
|
||||||
<td align="center"><a href="https://github.com/Jesse-Cameron"><img src="https://avatars3.githubusercontent.com/u/3723654?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jesse</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=Jesse-Cameron" title="Code">💻</a> <a href="#content-Jesse-Cameron" title="Content">🖋</a></td>
|
|
||||||
<td align="center"><a href="https://github.com/MrFroop"><img src="https://avatars3.githubusercontent.com/u/196700?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Fredrik Jambrén</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=MrFroop" title="Code">💻</a></td>
|
|
||||||
<td align="center"><a href="https://github.com/petemcfarlane"><img src="https://avatars3.githubusercontent.com/u/3472717?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Pete McFarlane</b></sub></a><br /><a href="#content-petemcfarlane" title="Content">🖋</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td align="center"><a href="https://github.com/nkanderson"><img src="https://avatars0.githubusercontent.com/u/4128825?v=4?s=100" width="100px;" alt=""/><br /><sub><b>nkanderson</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=nkanderson" title="Code">💻</a> <a href="#content-nkanderson" title="Content">🖋</a></td>
|
|
||||||
<td align="center"><a href="https://github.com/ajaxm"><img src="https://avatars0.githubusercontent.com/u/13360138?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ajax M</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=ajaxm" title="Documentation">📖</a></td>
|
|
||||||
<td align="center"><a href="https://dylnuge.com"><img src="https://avatars2.githubusercontent.com/u/118624?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Dylan Nugent</b></sub></a><br /><a href="#content-Dylnuge" title="Content">🖋</a></td>
|
|
||||||
<td align="center"><a href="https://github.com/vyaslav"><img src="https://avatars0.githubusercontent.com/u/1385427?v=4?s=100" width="100px;" alt=""/><br /><sub><b>vyaslav</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=vyaslav" title="Code">💻</a> <a href="#content-vyaslav" title="Content">🖋</a></td>
|
|
||||||
<td align="center"><a href="https://join.sfxd.org"><img src="https://avatars1.githubusercontent.com/u/17297466?v=4?s=100" width="100px;" alt=""/><br /><sub><b>George</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=gdoenlen" title="Code">💻</a></td>
|
|
||||||
<td align="center"><a href="https://github.com/nyxtom"><img src="https://avatars2.githubusercontent.com/u/222763?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Thomas Holloway</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=nyxtom" title="Code">💻</a> <a href="#content-nyxtom" title="Content">🖋</a></td>
|
|
||||||
<td align="center"><a href="https://github.com/workingjubilee"><img src="https://avatars1.githubusercontent.com/u/46493976?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jubilee</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=workingjubilee" title="Code">💻</a></td>
|
|
||||||
<td align="center"><a href="https://github.com/WofWca"><img src="https://avatars1.githubusercontent.com/u/39462442?v=4?s=100" width="100px;" alt=""/><br /><sub><b>WofWca</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=WofWca" title="Code">💻</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td align="center"><a href="https://github.com/jrvidal"><img src="https://avatars0.githubusercontent.com/u/1636604?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Roberto Vidal</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=jrvidal" title="Code">💻</a> <a href="https://github.com/rust-lang/rustlings/commits?author=jrvidal" title="Documentation">📖</a> <a href="#ideas-jrvidal" title="Ideas, Planning, & Feedback">🤔</a> <a href="#maintenance-jrvidal" title="Maintenance">🚧</a></td>
|
|
||||||
<td align="center"><a href="https://github.com/jensim"><img src="https://avatars0.githubusercontent.com/u/3663856?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jens</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=jensim" title="Documentation">📖</a></td>
|
|
||||||
<td align="center"><a href="http://rahatah.me/d"><img src="https://avatars3.githubusercontent.com/u/3174006?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Rahat Ahmed</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=rahatarmanahmed" title="Documentation">📖</a></td>
|
|
||||||
<td align="center"><a href="https://github.com/AbdouSeck"><img src="https://avatars2.githubusercontent.com/u/6490055?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Abdou Seck</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=AbdouSeck" title="Code">💻</a> <a href="#content-AbdouSeck" title="Content">🖋</a> <a href="https://github.com/rust-lang/rustlings/pulls?q=is%3Apr+reviewed-by%3AAbdouSeck" title="Reviewed Pull Requests">👀</a></td>
|
|
||||||
<td align="center"><a href="https://codehearts.com"><img src="https://avatars0.githubusercontent.com/u/2885412?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Katie</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=codehearts" title="Code">💻</a></td>
|
|
||||||
<td align="center"><a href="https://github.com/Socratides"><img src="https://avatars3.githubusercontent.com/u/27732983?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Socrates</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=Socratides" title="Documentation">📖</a></td>
|
|
||||||
<td align="center"><a href="https://github.com/gnodarse"><img src="https://avatars3.githubusercontent.com/u/46761795?v=4?s=100" width="100px;" alt=""/><br /><sub><b>gnodarse</b></sub></a><br /><a href="#content-gnodarse" title="Content">🖋</a></td>
|
|
||||||
<td align="center"><a href="https://github.com/harrisonmetz"><img src="https://avatars1.githubusercontent.com/u/7883408?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Harrison Metzger</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=harrisonmetz" title="Code">💻</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td align="center"><a href="https://github.com/TorbenJ"><img src="https://avatars2.githubusercontent.com/u/9077102?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Torben Jonas</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=TorbenJ" title="Code">💻</a> <a href="#content-TorbenJ" title="Content">🖋</a></td>
|
|
||||||
<td align="center"><a href="http://paulbissex.com/"><img src="https://avatars0.githubusercontent.com/u/641?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Paul Bissex</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=pbx" title="Documentation">📖</a></td>
|
|
||||||
<td align="center"><a href="https://github.com/sjmann"><img src="https://avatars0.githubusercontent.com/u/6589896?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Steven Mann</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=sjmann" title="Code">💻</a> <a href="#content-sjmann" title="Content">🖋</a></td>
|
|
||||||
<td align="center"><a href="https://smmdb.net/"><img src="https://avatars2.githubusercontent.com/u/5855071?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Mario Reder</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=Tarnadas" title="Code">💻</a> <a href="#content-Tarnadas" title="Content">🖋</a></td>
|
|
||||||
<td align="center"><a href="https://keybase.io/skim"><img src="https://avatars0.githubusercontent.com/u/47347?v=4?s=100" width="100px;" alt=""/><br /><sub><b>skim</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=sl4m" title="Code">💻</a></td>
|
|
||||||
<td align="center"><a href="https://github.com/sanjaykdragon"><img src="https://avatars1.githubusercontent.com/u/10261698?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Sanjay K</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=sanjaykdragon" title="Code">💻</a> <a href="#content-sanjaykdragon" title="Content">🖋</a></td>
|
|
||||||
<td align="center"><a href="http://www.rohanjain.in"><img src="https://avatars1.githubusercontent.com/u/343499?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Rohan Jain</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=crodjer" title="Code">💻</a></td>
|
|
||||||
<td align="center"><a href="https://www.saidaspen.se"><img src="https://avatars1.githubusercontent.com/u/7727687?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Said Aspen</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=saidaspen" title="Code">💻</a> <a href="#content-saidaspen" title="Content">🖋</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td align="center"><a href="https://github.com/uce"><img src="https://avatars3.githubusercontent.com/u/1756620?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ufuk Celebi</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=uce" title="Code">💻</a></td>
|
|
||||||
<td align="center"><a href="https://github.com/lebedevsergey"><img src="https://avatars2.githubusercontent.com/u/7325764?v=4?s=100" width="100px;" alt=""/><br /><sub><b>lebedevsergey</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=lebedevsergey" title="Documentation">📖</a></td>
|
|
||||||
<td align="center"><a href="https://github.com/avrong"><img src="https://avatars2.githubusercontent.com/u/6342851?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Aleksei Trifonov</b></sub></a><br /><a href="#content-avrong" title="Content">🖋</a></td>
|
|
||||||
<td align="center"><a href="https://drn.ie"><img src="https://avatars2.githubusercontent.com/u/411136?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Darren Meehan</b></sub></a><br /><a href="#content-Darrenmeehan" title="Content">🖋</a></td>
|
|
||||||
<td align="center"><a href="https://github.com/jihchi"><img src="https://avatars1.githubusercontent.com/u/87983?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jihchi Lee</b></sub></a><br /><a href="#content-jihchi" title="Content">🖋</a></td>
|
|
||||||
<td align="center"><a href="https://github.com/bertonha"><img src="https://avatars3.githubusercontent.com/u/1225902?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Christofer Bertonha</b></sub></a><br /><a href="#content-bertonha" title="Content">🖋</a></td>
|
|
||||||
<td align="center"><a href="https://github.com/apatniv"><img src="https://avatars2.githubusercontent.com/u/22565917?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Vivek Bharath Akupatni</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=apatniv" title="Code">💻</a> <a href="https://github.com/rust-lang/rustlings/commits?author=apatniv" title="Tests">⚠️</a></td>
|
|
||||||
<td align="center"><a href="https://github.com/DiD92"><img src="https://avatars3.githubusercontent.com/u/6002416?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Dídac Sementé Fernández</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=DiD92" title="Code">💻</a> <a href="#content-DiD92" title="Content">🖋</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td align="center"><a href="https://github.com/wrobstory"><img src="https://avatars3.githubusercontent.com/u/2601457?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Rob Story</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=wrobstory" title="Code">💻</a></td>
|
|
||||||
<td align="center"><a href="https://github.com/siobhanjacobson"><img src="https://avatars2.githubusercontent.com/u/28983835?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Siobhan Jacobson</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=siobhanjacobson" title="Code">💻</a></td>
|
|
||||||
<td align="center"><a href="https://www.linkedin.com/in/evancarroll/"><img src="https://avatars2.githubusercontent.com/u/19922?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Evan Carroll</b></sub></a><br /><a href="#content-EvanCarroll" title="Content">🖋</a></td>
|
|
||||||
<td align="center"><a href="http://www.jawaadmahmood.com"><img src="https://avatars3.githubusercontent.com/u/95606?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jawaad Mahmood</b></sub></a><br /><a href="#content-jmahmood" title="Content">🖋</a></td>
|
|
||||||
<td align="center"><a href="https://github.com/GaurangTandon"><img src="https://avatars1.githubusercontent.com/u/6308683?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Gaurang Tandon</b></sub></a><br /><a href="#content-GaurangTandon" title="Content">🖋</a></td>
|
|
||||||
<td align="center"><a href="https://github.com/dev-cyprium"><img src="https://avatars1.githubusercontent.com/u/6002628?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Stefan Kupresak</b></sub></a><br /><a href="#content-dev-cyprium" title="Content">🖋</a></td>
|
|
||||||
<td align="center"><a href="https://github.com/greg-el"><img src="https://avatars3.githubusercontent.com/u/45019882?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Greg Leonard</b></sub></a><br /><a href="#content-greg-el" title="Content">🖋</a></td>
|
|
||||||
<td align="center"><a href="https://ryanpcmcquen.org"><img src="https://avatars3.githubusercontent.com/u/772937?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ryan McQuen</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=ryanpcmcquen" title="Code">💻</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td align="center"><a href="https://github.com/AnnikaCodes"><img src="https://avatars3.githubusercontent.com/u/56906084?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Annika</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/pulls?q=is%3Apr+reviewed-by%3AAnnikaCodes" title="Reviewed Pull Requests">👀</a></td>
|
|
||||||
<td align="center"><a href="https://darnuria.eu"><img src="https://avatars1.githubusercontent.com/u/2827553?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Axel Viala</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=darnuria" title="Code">💻</a></td>
|
|
||||||
<td align="center"><a href="https://sazid.github.io"><img src="https://avatars1.githubusercontent.com/u/2370167?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Mohammed Sazid Al Rashid</b></sub></a><br /><a href="#content-sazid" title="Content">🖋</a> <a href="https://github.com/rust-lang/rustlings/commits?author=sazid" title="Code">💻</a></td>
|
|
||||||
<td align="center"><a href="https://codingthemsoftly.com"><img src="https://avatars1.githubusercontent.com/u/17479099?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Caleb Webber</b></sub></a><br /><a href="#maintenance-seeplusplus" title="Maintenance">🚧</a></td>
|
|
||||||
<td align="center"><a href="https://github.com/pcn"><img src="https://avatars2.githubusercontent.com/u/1056756?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Peter N</b></sub></a><br /><a href="#maintenance-pcn" title="Maintenance">🚧</a></td>
|
|
||||||
<td align="center"><a href="https://github.com/seancad"><img src="https://avatars1.githubusercontent.com/u/47405611?v=4?s=100" width="100px;" alt=""/><br /><sub><b>seancad</b></sub></a><br /><a href="#maintenance-seancad" title="Maintenance">🚧</a></td>
|
|
||||||
<td align="center"><a href="http://willhayworth.com"><img src="https://avatars3.githubusercontent.com/u/181174?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Will Hayworth</b></sub></a><br /><a href="#content-wsh" title="Content">🖋</a></td>
|
|
||||||
<td align="center"><a href="https://github.com/chrizel"><img src="https://avatars3.githubusercontent.com/u/20802?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Christian Zeller</b></sub></a><br /><a href="#content-chrizel" title="Content">🖋</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td align="center"><a href="https://github.com/jfchevrette"><img src="https://avatars.githubusercontent.com/u/3001?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jean-Francois Chevrette</b></sub></a><br /><a href="#content-jfchevrette" title="Content">🖋</a> <a href="https://github.com/rust-lang/rustlings/commits?author=jfchevrette" title="Code">💻</a></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<!-- markdownlint-restore -->
|
|
||||||
<!-- prettier-ignore-end -->
|
|
||||||
|
|
||||||
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
|
||||||
|
|
||||||
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
|
|
|
@ -1,8 +1,10 @@
|
||||||
### Clippy
|
# Clippy
|
||||||
|
|
||||||
The Clippy tool is a collection of lints to analyze your code so you can catch common mistakes and improve your Rust code.
|
The Clippy tool is a collection of lints to analyze your code so you can catch common mistakes and improve your Rust code.
|
||||||
|
|
||||||
If you used the installation script for Rustlings, Clippy should be already installed.
|
If you used the installation script for Rustlings, Clippy should be already installed.
|
||||||
If not you can install it manually via `rustup component add clippy`.
|
If not you can install it manually via `rustup component add clippy`.
|
||||||
|
|
||||||
For more information about Clippy lints, please see [their documentation page](https://rust-lang.github.io/rust-clippy/master/).
|
## Further information
|
||||||
|
|
||||||
|
- [GitHub Repository](https://github.com/rust-lang/rust-clippy).
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
### Collections
|
# Collections
|
||||||
|
|
||||||
Rust’s standard library includes a number of very useful data
|
Rust’s standard library includes a number of very useful data
|
||||||
structures called collections. Most other data types represent one
|
structures called collections. Most other data types represent one
|
||||||
|
@ -14,7 +14,9 @@ structures that are used very often in Rust programs:
|
||||||
* A *vector* allows you to store a variable number of values next to
|
* A *vector* allows you to store a variable number of values next to
|
||||||
each other.
|
each other.
|
||||||
* A *hash map* allows you to associate a value with a particular key.
|
* A *hash map* allows you to associate a value with a particular key.
|
||||||
You may also know this by the names *map* in C++, *dictionary* in
|
You may also know this by the names [*unordered map* in C++](https://en.cppreference.com/w/cpp/container/unordered_map),
|
||||||
Python or an *associative array* in other languages.
|
[*dictionary* in Python](https://docs.python.org/3/tutorial/datastructures.html#dictionaries) or an *associative array* in other languages.
|
||||||
|
|
||||||
[Rust book chapter](https://doc.rust-lang.org/stable/book/ch08-01-vectors.html)
|
## Further information
|
||||||
|
|
||||||
|
- [Storing Lists of Values with Vectors](https://doc.rust-lang.org/stable/book/ch08-01-vectors.html)
|
||||||
|
|
|
@ -8,21 +8,21 @@
|
||||||
//
|
//
|
||||||
// Make me compile and pass the tests!
|
// Make me compile and pass the tests!
|
||||||
//
|
//
|
||||||
// Execute the command `rustlings hint collections3` if you need
|
// Execute the command `rustlings hint hashmap1` if you need
|
||||||
// hints.
|
// hints.
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
fn fruit_basket() -> HashMap<String, u32> {
|
fn fruit_basket() -> HashMap<String, u32> {
|
||||||
let mut basket = // TODO: declare your hash map here.
|
let mut basket = HashMap::new(); // TODO: declare your hash map here.
|
||||||
|
|
||||||
// Two bananas are already given for you :)
|
// Two bananas are already given for you :)
|
||||||
basket.insert(String::from("banana"), 2);
|
basket.insert(String::from("banana"), 2);
|
||||||
|
|
||||||
// TODO: Put more fruits in your basket here.
|
// TODO: Put more fruits in your basket here.
|
||||||
|
basket.insert(String::from("peach"), 2);
|
||||||
|
basket.insert(String::from("mango"), 2);
|
||||||
|
basket.insert(String::from("apple"), 2);
|
||||||
basket
|
basket
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,8 +39,6 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn at_least_five_fruits() {
|
fn at_least_five_fruits() {
|
||||||
let basket = fruit_basket();
|
let basket = fruit_basket();
|
||||||
assert!(basket
|
assert!(basket.values().sum::<u32>() >= 5);
|
||||||
.values()
|
|
||||||
.sum::<u32>() >= 5);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,16 +4,14 @@
|
||||||
// represents the name of the fruit and the value represents how many
|
// represents the name of the fruit and the value represents how many
|
||||||
// of that particular fruit is in the basket. You have to put *MORE
|
// of that particular fruit is in the basket. You have to put *MORE
|
||||||
// THAN 11* fruits in the basket. Three types of fruits - Apple (4),
|
// THAN 11* fruits in the basket. Three types of fruits - Apple (4),
|
||||||
// Mango (2) and Lichi (5) are already given in the basket. You are
|
// Mango (2) and Lychee (5) are already given in the basket. You are
|
||||||
// not allowed to insert any more of these fruits!
|
// not allowed to insert any more of these fruits!
|
||||||
//
|
//
|
||||||
// Make me pass the tests!
|
// Make me pass the tests!
|
||||||
//
|
//
|
||||||
// Execute the command `rustlings hint collections4` if you need
|
// Execute the command `rustlings hint hashmap2` if you need
|
||||||
// hints.
|
// hints.
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
#[derive(Hash, PartialEq, Eq)]
|
#[derive(Hash, PartialEq, Eq)]
|
||||||
|
@ -21,7 +19,7 @@ enum Fruit {
|
||||||
Apple,
|
Apple,
|
||||||
Banana,
|
Banana,
|
||||||
Mango,
|
Mango,
|
||||||
Lichi,
|
Lychee,
|
||||||
Pineapple,
|
Pineapple,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,14 +28,14 @@ fn fruit_basket(basket: &mut HashMap<Fruit, u32>) {
|
||||||
Fruit::Apple,
|
Fruit::Apple,
|
||||||
Fruit::Banana,
|
Fruit::Banana,
|
||||||
Fruit::Mango,
|
Fruit::Mango,
|
||||||
Fruit::Lichi,
|
Fruit::Lychee,
|
||||||
Fruit::Pineapple,
|
Fruit::Pineapple,
|
||||||
];
|
];
|
||||||
|
|
||||||
for fruit in fruit_kinds {
|
for fruit in fruit_kinds {
|
||||||
// TODO: Put new fruits if not already present. Note that you
|
if fruit == Fruit::Banana || fruit == Fruit::Pineapple {
|
||||||
// are not allowed to put any type of fruit that's already
|
basket.insert(fruit, 4);
|
||||||
// present!
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +47,7 @@ mod tests {
|
||||||
let mut basket = HashMap::<Fruit, u32>::new();
|
let mut basket = HashMap::<Fruit, u32>::new();
|
||||||
basket.insert(Fruit::Apple, 4);
|
basket.insert(Fruit::Apple, 4);
|
||||||
basket.insert(Fruit::Mango, 2);
|
basket.insert(Fruit::Mango, 2);
|
||||||
basket.insert(Fruit::Lichi, 5);
|
basket.insert(Fruit::Lychee, 5);
|
||||||
|
|
||||||
basket
|
basket
|
||||||
}
|
}
|
||||||
|
@ -60,7 +58,7 @@ mod tests {
|
||||||
fruit_basket(&mut basket);
|
fruit_basket(&mut basket);
|
||||||
assert_eq!(*basket.get(&Fruit::Apple).unwrap(), 4);
|
assert_eq!(*basket.get(&Fruit::Apple).unwrap(), 4);
|
||||||
assert_eq!(*basket.get(&Fruit::Mango).unwrap(), 2);
|
assert_eq!(*basket.get(&Fruit::Mango).unwrap(), 2);
|
||||||
assert_eq!(*basket.get(&Fruit::Lichi).unwrap(), 5);
|
assert_eq!(*basket.get(&Fruit::Lychee).unwrap(), 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -68,16 +66,14 @@ mod tests {
|
||||||
let mut basket = get_fruit_basket();
|
let mut basket = get_fruit_basket();
|
||||||
fruit_basket(&mut basket);
|
fruit_basket(&mut basket);
|
||||||
let count_fruit_kinds = basket.len();
|
let count_fruit_kinds = basket.len();
|
||||||
assert!(count_fruit_kinds == 5);
|
assert!(count_fruit_kinds >= 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn greater_than_eleven_fruits() {
|
fn greater_than_eleven_fruits() {
|
||||||
let mut basket = get_fruit_basket();
|
let mut basket = get_fruit_basket();
|
||||||
fruit_basket(&mut basket);
|
fruit_basket(&mut basket);
|
||||||
let count = basket
|
let count = basket.values().sum::<u32>();
|
||||||
.values()
|
|
||||||
.sum::<u32>();
|
|
||||||
assert!(count > 11);
|
assert!(count > 11);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,13 +2,11 @@
|
||||||
// Your task is to create a `Vec` which holds the exact same elements
|
// Your task is to create a `Vec` which holds the exact same elements
|
||||||
// as in the array `a`.
|
// as in the array `a`.
|
||||||
// Make me compile and pass the test!
|
// Make me compile and pass the test!
|
||||||
// Execute the command `rustlings hint collections1` if you need hints.
|
// Execute the command `rustlings hint vec1` if you need hints.
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn array_and_vec() -> ([i32; 4], Vec<i32>) {
|
fn array_and_vec() -> ([i32; 4], Vec<i32>) {
|
||||||
let a = [10, 20, 30, 40]; // a plain array
|
let a = [10, 20, 30, 40]; // a plain array
|
||||||
let v = // TODO: declare your vector here with the macro for vectors
|
let v = vec![10,20,30,40]; // TODO: declare your vector here with the macro for vectors
|
||||||
|
|
||||||
(a, v)
|
(a, v)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,15 +4,17 @@
|
||||||
//
|
//
|
||||||
// Make me pass the test!
|
// Make me pass the test!
|
||||||
//
|
//
|
||||||
// Execute the command `rustlings hint collections2` if you need
|
// Execute the command `rustlings hint vec2` if you need
|
||||||
// hints.
|
// hints.
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn vec_loop(mut v: Vec<i32>) -> Vec<i32> {
|
fn vec_loop(mut v: Vec<i32>) -> Vec<i32> {
|
||||||
for i in v.iter_mut() {
|
for i in v.iter_mut() {
|
||||||
// TODO: Fill this up so that each element in the Vec `v` is
|
// TODO: Fill this up so that each element in the Vec `v` is
|
||||||
// multiplied by 2.
|
// multiplied by 2.
|
||||||
|
|
||||||
|
// *i accesses a specific object in vector?
|
||||||
|
// *= 2 multiplies it by 2
|
||||||
|
*i *= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// At this point, `v` should be equal to [4, 8, 12, 16, 20].
|
// At this point, `v` should be equal to [4, 8, 12, 16, 20].
|
||||||
|
@ -28,11 +30,6 @@ mod tests {
|
||||||
let v: Vec<i32> = (1..).filter(|x| x % 2 == 0).take(5).collect();
|
let v: Vec<i32> = (1..).filter(|x| x % 2 == 0).take(5).collect();
|
||||||
let ans = vec_loop(v.clone());
|
let ans = vec_loop(v.clone());
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(ans, v.iter().map(|x| x * 2).collect::<Vec<i32>>());
|
||||||
ans,
|
|
||||||
v.iter()
|
|
||||||
.map(|x| x * 2)
|
|
||||||
.collect::<Vec<i32>>()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
### Type conversions
|
# Type conversions
|
||||||
|
|
||||||
|
|
||||||
Rust offers a multitude of ways to convert a value of a given type into another type.
|
Rust offers a multitude of ways to convert a value of a given type into another type.
|
||||||
|
|
||||||
|
@ -15,6 +14,8 @@ Furthermore, the `std::str` module offers a trait called [`FromStr`](https://doc
|
||||||
|
|
||||||
These should be the main ways ***within the standard library*** to convert data into your desired types.
|
These should be the main ways ***within the standard library*** to convert data into your desired types.
|
||||||
|
|
||||||
#### Book Sections
|
## Further information
|
||||||
|
|
||||||
These are not directly covered in the book, but the standard library has great documentation for [conversions here](https://doc.rust-lang.org/std/convert/index.html). The `FromStr` trait is also covered [here](https://doc.rust-lang.org/std/str/trait.FromStr.html).
|
These are not directly covered in the book, but the standard library has a great documentation for it.
|
||||||
|
- [conversions](https://doc.rust-lang.org/std/convert/index.html)
|
||||||
|
- [`FromStr` trait](https://doc.rust-lang.org/std/str/trait.FromStr.html)
|
|
@ -2,6 +2,7 @@
|
||||||
// Additionally, upon implementing FromStr, you can use the `parse` method
|
// Additionally, upon implementing FromStr, you can use the `parse` method
|
||||||
// on strings to generate an object of the implementor type.
|
// on strings to generate an object of the implementor type.
|
||||||
// You can read more about it at https://doc.rust-lang.org/std/str/trait.FromStr.html
|
// You can read more about it at https://doc.rust-lang.org/std/str/trait.FromStr.html
|
||||||
|
use std::error;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -13,17 +14,17 @@ struct Person {
|
||||||
// I AM NOT DONE
|
// I AM NOT DONE
|
||||||
|
|
||||||
// Steps:
|
// Steps:
|
||||||
// 1. If the length of the provided string is 0 an error should be returned
|
// 1. If the length of the provided string is 0, an error should be returned
|
||||||
// 2. Split the given string on the commas present in it
|
// 2. Split the given string on the commas present in it
|
||||||
// 3. Only 2 elements should returned from the split, otherwise return an error
|
// 3. Only 2 elements should be returned from the split, otherwise return an error
|
||||||
// 4. Extract the first element from the split operation and use it as the name
|
// 4. Extract the first element from the split operation and use it as the name
|
||||||
// 5. Extract the other element from the split operation and parse it into a `usize` as the age
|
// 5. Extract the other element from the split operation and parse it into a `usize` as the age
|
||||||
// with something like `"4".parse::<usize>()`.
|
// with something like `"4".parse::<usize>()`
|
||||||
// 5. If while extracting the name and the age something goes wrong an error should be returned
|
// 5. If while extracting the name and the age something goes wrong, an error should be returned
|
||||||
// If everything goes well, then return a Result of a Person object
|
// If everything goes well, then return a Result of a Person object
|
||||||
|
|
||||||
impl FromStr for Person {
|
impl FromStr for Person {
|
||||||
type Err = String;
|
type Err = Box<dyn error::Error>;
|
||||||
fn from_str(s: &str) -> Result<Person, Self::Err> {
|
fn from_str(s: &str) -> Result<Person, Self::Err> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
// instead of the target type itself.
|
// instead of the target type itself.
|
||||||
// You can read more about it at https://doc.rust-lang.org/std/convert/trait.TryFrom.html
|
// You can read more about it at https://doc.rust-lang.org/std/convert/trait.TryFrom.html
|
||||||
use std::convert::{TryFrom, TryInto};
|
use std::convert::{TryFrom, TryInto};
|
||||||
|
use std::error;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
struct Color {
|
struct Color {
|
||||||
|
@ -24,19 +25,19 @@ struct Color {
|
||||||
|
|
||||||
// Tuple implementation
|
// Tuple implementation
|
||||||
impl TryFrom<(i16, i16, i16)> for Color {
|
impl TryFrom<(i16, i16, i16)> for Color {
|
||||||
type Error = String;
|
type Error = Box<dyn error::Error>;
|
||||||
fn try_from(tuple: (i16, i16, i16)) -> Result<Self, Self::Error> {}
|
fn try_from(tuple: (i16, i16, i16)) -> Result<Self, Self::Error> {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Array implementation
|
// Array implementation
|
||||||
impl TryFrom<[i16; 3]> for Color {
|
impl TryFrom<[i16; 3]> for Color {
|
||||||
type Error = String;
|
type Error = Box<dyn error::Error>;
|
||||||
fn try_from(arr: [i16; 3]) -> Result<Self, Self::Error> {}
|
fn try_from(arr: [i16; 3]) -> Result<Self, Self::Error> {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Slice implementation
|
// Slice implementation
|
||||||
impl TryFrom<&[i16]> for Color {
|
impl TryFrom<&[i16]> for Color {
|
||||||
type Error = String;
|
type Error = Box<dyn error::Error>;
|
||||||
fn try_from(slice: &[i16]) -> Result<Self, Self::Error> {}
|
fn try_from(slice: &[i16]) -> Result<Self, Self::Error> {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,41 +77,43 @@ mod tests {
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn test_tuple_correct() {
|
fn test_tuple_correct() {
|
||||||
let c: Result<Color, String> = (183, 65, 14).try_into();
|
let c: Result<Color, _> = (183, 65, 14).try_into();
|
||||||
|
assert!(c.is_ok());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
c,
|
c.unwrap(),
|
||||||
Ok(Color {
|
Color {
|
||||||
red: 183,
|
red: 183,
|
||||||
green: 65,
|
green: 65,
|
||||||
blue: 14
|
blue: 14
|
||||||
})
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn test_array_out_of_range_positive() {
|
fn test_array_out_of_range_positive() {
|
||||||
let c: Result<Color, String> = [1000, 10000, 256].try_into();
|
let c: Result<Color, _> = [1000, 10000, 256].try_into();
|
||||||
assert!(c.is_err());
|
assert!(c.is_err());
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn test_array_out_of_range_negative() {
|
fn test_array_out_of_range_negative() {
|
||||||
let c: Result<Color, String> = [-10, -256, -1].try_into();
|
let c: Result<Color, _> = [-10, -256, -1].try_into();
|
||||||
assert!(c.is_err());
|
assert!(c.is_err());
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn test_array_sum() {
|
fn test_array_sum() {
|
||||||
let c: Result<Color, String> = [-1, 255, 255].try_into();
|
let c: Result<Color, _> = [-1, 255, 255].try_into();
|
||||||
assert!(c.is_err());
|
assert!(c.is_err());
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn test_array_correct() {
|
fn test_array_correct() {
|
||||||
let c: Result<Color, String> = [183, 65, 14].try_into();
|
let c: Result<Color, _> = [183, 65, 14].try_into();
|
||||||
|
assert!(c.is_ok());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
c,
|
c.unwrap(),
|
||||||
Ok(Color {
|
Color {
|
||||||
red: 183,
|
red: 183,
|
||||||
green: 65,
|
green: 65,
|
||||||
blue: 14
|
blue: 14
|
||||||
})
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -131,14 +134,15 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_slice_correct() {
|
fn test_slice_correct() {
|
||||||
let v = vec![183, 65, 14];
|
let v = vec![183, 65, 14];
|
||||||
let c: Result<Color, String> = Color::try_from(&v[..]);
|
let c: Result<Color, _> = Color::try_from(&v[..]);
|
||||||
|
assert!(c.is_ok());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
c,
|
c.unwrap(),
|
||||||
Ok(Color {
|
Color {
|
||||||
red: 183,
|
red: 183,
|
||||||
green: 65,
|
green: 65,
|
||||||
blue: 14
|
blue: 14
|
||||||
})
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
### Enums
|
# Enums
|
||||||
|
|
||||||
Rust allows you to define types called "enums" which enumerate possible values.
|
Rust allows you to define types called "enums" which enumerate possible values.
|
||||||
Enums are a feature in many languages, but their capabilities differ in each language. Rust’s enums are most similar to algebraic data types in functional languages, such as F#, OCaml, and Haskell.
|
Enums are a feature in many languages, but their capabilities differ in each language. Rust’s enums are most similar to algebraic data types in functional languages, such as F#, OCaml, and Haskell.
|
||||||
Useful in combination with enums is Rust's "pattern matching" facility, which makes it easy to run different code for different values of an enumeration.
|
Useful in combination with enums is Rust's "pattern matching" facility, which makes it easy to run different code for different values of an enumeration.
|
||||||
|
|
||||||
#### Book Sections
|
## Further information
|
||||||
|
|
||||||
- [Enums](https://doc.rust-lang.org/book/ch06-00-enums.html)
|
- [Enums](https://doc.rust-lang.org/book/ch06-00-enums.html)
|
||||||
- [Pattern syntax](https://doc.rust-lang.org/book/ch18-03-pattern-syntax.html)
|
- [Pattern syntax](https://doc.rust-lang.org/book/ch18-03-pattern-syntax.html)
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
// enums1.rs
|
// enums1.rs
|
||||||
// Make me compile! Execute `rustlings hint enums1` for hints!
|
// Make me compile! Execute `rustlings hint enums1` for hints!
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
enum Message {
|
enum Message {
|
||||||
// TODO: define a few types of messages as used below
|
Quit,
|
||||||
|
Echo,
|
||||||
|
Move,
|
||||||
|
ChangeColor
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
// enums2.rs
|
// enums2.rs
|
||||||
// Make me compile! Execute `rustlings hint enums2` for hints!
|
// Make me compile! Execute `rustlings hint enums2` for hints!
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
enum Message {
|
enum Message {
|
||||||
// TODO: define the different variants used below
|
Move { x: i32, y: i32 },
|
||||||
|
Echo(String),
|
||||||
|
ChangeColor(i32,i32,i32),
|
||||||
|
Quit
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Message {
|
impl Message {
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
// enums3.rs
|
// enums3.rs
|
||||||
// Address all the TODOs to make the tests pass!
|
// Address all the TODOs to make the tests pass!
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
enum Message {
|
enum Message {
|
||||||
// TODO: implement the message variant types based on their usage below
|
Move(Point),
|
||||||
|
Echo(String),
|
||||||
|
ChangeColor((u8,u8,u8)),
|
||||||
|
Quit
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Point {
|
struct Point {
|
||||||
|
@ -37,6 +38,13 @@ impl State {
|
||||||
|
|
||||||
fn process(&mut self, message: Message) {
|
fn process(&mut self, message: Message) {
|
||||||
// TODO: create a match expression to process the different message variants
|
// TODO: create a match expression to process the different message variants
|
||||||
|
match message {
|
||||||
|
Message::ChangeColor((r,g,b)) => self.change_color((r,g,b)),
|
||||||
|
Message::Echo(String) => self.echo(String),
|
||||||
|
Message::Move(Pointer) => self.move_position(Pointer),
|
||||||
|
Message::Quit => self.quit(),
|
||||||
|
_ => panic!("NOTHING SUPPLIED D:"),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
For this exercise check out the sections:
|
# Error handling
|
||||||
|
Most errors aren’t serious enough to require the program to stop entirely.
|
||||||
|
Sometimes, when a function fails, it’s for a reason that you can easily interpret and respond to.
|
||||||
|
For example, if you try to open a file and that operation fails because the file doesn’t exist, you might want to create the file instead of terminating the process.
|
||||||
|
|
||||||
|
## Further information
|
||||||
|
|
||||||
- [Error Handling](https://doc.rust-lang.org/book/ch09-02-recoverable-errors-with-result.html)
|
- [Error Handling](https://doc.rust-lang.org/book/ch09-02-recoverable-errors-with-result.html)
|
||||||
- [Generics](https://doc.rust-lang.org/book/ch10-01-syntax.html)
|
- [Generics](https://doc.rust-lang.org/book/ch10-01-syntax.html)
|
||||||
|
- [Result](https://doc.rust-lang.org/rust-by-example/error/result.html)
|
||||||
of the Rust Book.
|
- [Boxing errors](https://doc.rust-lang.org/rust-by-example/error/multiple_error_types/boxing_errors.html)
|
||||||
|
|
|
@ -6,14 +6,12 @@
|
||||||
// this function to have.
|
// this function to have.
|
||||||
// Execute `rustlings hint errors1` for hints!
|
// Execute `rustlings hint errors1` for hints!
|
||||||
|
|
||||||
// I AM NOT DONE
|
pub fn generate_nametag_text(name: String) -> Result<String, String> {
|
||||||
|
|
||||||
pub fn generate_nametag_text(name: String) -> Option<String> {
|
|
||||||
if name.len() > 0 {
|
if name.len() > 0 {
|
||||||
Some(format!("Hi! My name is {}", name))
|
Ok(format!("Hi! My name is {}", name))
|
||||||
} else {
|
} else {
|
||||||
// Empty names aren't allowed.
|
// Empty names aren't allowed.
|
||||||
None
|
Err("Empty names aren't allowed.".to_owned())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,11 +26,12 @@ mod tests {
|
||||||
fn generates_nametag_text_for_a_nonempty_name() {
|
fn generates_nametag_text_for_a_nonempty_name() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
generate_nametag_text("Beyoncé".into()),
|
generate_nametag_text("Beyoncé".into()),
|
||||||
Some("Hi! My name is Beyoncé".into())
|
Ok("Hi! My name is Beyoncé".into())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
#[should_panic]
|
||||||
fn explains_why_generating_nametag_text_fails() {
|
fn explains_why_generating_nametag_text_fails() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
generate_nametag_text("".into()),
|
generate_nametag_text("".into()),
|
||||||
|
|
|
@ -16,14 +16,12 @@
|
||||||
// There are at least two ways to implement this that are both correct-- but
|
// There are at least two ways to implement this that are both correct-- but
|
||||||
// one is a lot shorter! Execute `rustlings hint errors2` for hints to both ways.
|
// one is a lot shorter! Execute `rustlings hint errors2` for hints to both ways.
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
use std::num::ParseIntError;
|
use std::num::ParseIntError;
|
||||||
|
|
||||||
pub fn total_cost(item_quantity: &str) -> Result<i32, ParseIntError> {
|
pub fn total_cost(item_quantity: &str) -> Result<i32, ParseIntError> {
|
||||||
let processing_fee = 1;
|
let processing_fee = 1;
|
||||||
let cost_per_item = 5;
|
let cost_per_item = 5;
|
||||||
let qty = item_quantity.parse::<i32>();
|
let qty = item_quantity.parse::<i32>()?;
|
||||||
|
|
||||||
Ok(qty * cost_per_item + processing_fee)
|
Ok(qty * cost_per_item + processing_fee)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,11 +4,12 @@
|
||||||
// Why not? What should we do to fix it?
|
// Why not? What should we do to fix it?
|
||||||
// Execute `rustlings hint errors3` for hints!
|
// Execute `rustlings hint errors3` for hints!
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
use std::num::ParseIntError;
|
use std::num::ParseIntError;
|
||||||
|
|
||||||
fn main() {
|
// In previous excercises we were taught that Result can output
|
||||||
|
// i32 and ParseIntError, but nobody told us that Result can also
|
||||||
|
// output () instead of i32... oops
|
||||||
|
fn main() -> Result<(), ParseIntError> {
|
||||||
let mut tokens = 100;
|
let mut tokens = 100;
|
||||||
let pretend_user_input = "8";
|
let pretend_user_input = "8";
|
||||||
|
|
||||||
|
@ -20,6 +21,8 @@ fn main() {
|
||||||
tokens -= cost;
|
tokens -= cost;
|
||||||
println!("You now have {} tokens.", tokens);
|
println!("You now have {} tokens.", tokens);
|
||||||
}
|
}
|
||||||
|
// No need for Err() because `?` operator already handles it well
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn total_cost(item_quantity: &str) -> Result<i32, ParseIntError> {
|
pub fn total_cost(item_quantity: &str) -> Result<i32, ParseIntError> {
|
||||||
|
|
|
@ -17,19 +17,17 @@
|
||||||
//
|
//
|
||||||
// Execute `rustlings hint errorsn` for hints :)
|
// Execute `rustlings hint errorsn` for hints :)
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
use std::error;
|
use std::error;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
// PositiveNonzeroInteger is a struct defined below the tests.
|
// PositiveNonzeroInteger is a struct defined below the tests.
|
||||||
fn read_and_validate(b: &mut dyn io::BufRead) -> Result<PositiveNonzeroInteger, ???> {
|
fn read_and_validate(b: &mut dyn io::BufRead) -> Result<PositiveNonzeroInteger, Box<dyn error::Error>> {
|
||||||
let mut line = String::new();
|
let mut line = String::new();
|
||||||
b.read_line(&mut line);
|
b.read_line(&mut line)?;
|
||||||
let num: i64 = line.trim().parse();
|
let num: i64 = line.trim().parse()?;
|
||||||
let answer = PositiveNonzeroInteger::new(num);
|
let answer = PositiveNonzeroInteger::new(num)?;
|
||||||
answer
|
Ok(answer)
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
### Functions
|
# Functions
|
||||||
|
|
||||||
Here, you'll learn how to write functions and how Rust's compiler can trace things way back.
|
Here, you'll learn how to write functions and how Rust's compiler can trace things way back.
|
||||||
|
|
||||||
#### Book Sections
|
## Further information
|
||||||
|
|
||||||
- [How Functions Work](https://doc.rust-lang.org/book/ch03-03-how-functions-work.html)
|
- [How Functions Work](https://doc.rust-lang.org/book/ch03-03-how-functions-work.html)
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
// functions1.rs
|
// functions1.rs
|
||||||
// Make me compile! Execute `rustlings hint functions1` for hints :)
|
// Make me compile! Execute `rustlings hint functions1` for hints :)
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
call_me();
|
call_me();
|
||||||
}
|
}
|
||||||
|
fn call_me() {
|
||||||
|
println!("Called!");
|
||||||
|
}
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
// functions2.rs
|
// functions2.rs
|
||||||
// Make me compile! Execute `rustlings hint functions2` for hints :)
|
// Make me compile! Execute `rustlings hint functions2` for hints :)
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
call_me(3);
|
call_me(7);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call_me(num:) {
|
fn call_me(num:i32) {
|
||||||
for i in 0..num {
|
for i in 0..num {
|
||||||
println!("Ring! Call number {}", i + 1);
|
println!("Ring! Call number {}", i + 1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
// functions3.rs
|
// functions3.rs
|
||||||
// Make me compile! Execute `rustlings hint functions3` for hints :)
|
// Make me compile! Execute `rustlings hint functions3` for hints :)
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
call_me();
|
call_me(6);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call_me(num: i32) {
|
fn call_me(num: u32) {
|
||||||
for i in 0..num {
|
for i in 0..num {
|
||||||
println!("Ring! Call number {}", i + 1);
|
println!("Ring! Call number {}", i + 1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,14 +4,12 @@
|
||||||
// This store is having a sale where if the price is an even number, you get
|
// This store is having a sale where if the price is an even number, you get
|
||||||
// 10 Rustbucks off, but if it's an odd number, it's 3 Rustbucks off.
|
// 10 Rustbucks off, but if it's an odd number, it's 3 Rustbucks off.
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let original_price = 51;
|
let original_price = 51;
|
||||||
println!("Your sale price is {}", sale_price(original_price));
|
println!("Your sale price is {}", sale_price(original_price));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sale_price(price: i32) -> {
|
fn sale_price(price: i32) -> i32 {
|
||||||
if is_even(price) {
|
if is_even(price) {
|
||||||
price - 10
|
price - 10
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,13 +1,17 @@
|
||||||
// functions5.rs
|
// functions5.rs
|
||||||
// Make me compile! Execute `rustlings hint functions5` for hints :)
|
// Make me compile! Execute `rustlings hint functions5` for hints :)
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let answer = square(3);
|
let answer = square(3);
|
||||||
println!("The answer is {}", answer);
|
println!("The answer is {}", answer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// without ; the expression is a return statement
|
||||||
|
// it can be either both num * num or
|
||||||
|
// return num * num;
|
||||||
|
// but it cannot be
|
||||||
|
// return num * num OR num * num;
|
||||||
|
|
||||||
fn square(num: i32) -> i32 {
|
fn square(num: i32) -> i32 {
|
||||||
num * num;
|
num * num
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
### Generics
|
# Generics
|
||||||
|
|
||||||
In this section you'll learn about saving yourself many lines of code with generics!
|
Generics is the topic of generalizing types and functionalities to broader cases.
|
||||||
|
This is extremely useful for reducing code duplication in many ways, but can call for rather involving syntax.
|
||||||
|
Namely, being generic requires taking great care to specify over which types a generic type is actually considered valid.
|
||||||
|
The simplest and most common use of generics is for type parameters.
|
||||||
|
|
||||||
### Book Sections
|
## Further information
|
||||||
|
|
||||||
- [Generic Data Types](https://doc.rust-lang.org/stable/book/ch10-01-syntax.html)
|
- [Generic Data Types](https://doc.rust-lang.org/stable/book/ch10-01-syntax.html)
|
||||||
|
- [Bounds](https://doc.rust-lang.org/rust-by-example/generics/bounds.html)
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
// This shopping list program isn't compiling!
|
// This shopping list program isn't compiling!
|
||||||
// Use your knowledge of generics to fix it.
|
// Use your knowledge of generics to fix it.
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut shopping_list: Vec<?> = Vec::new();
|
let mut shopping_list: Vec<&str> = Vec::new();
|
||||||
shopping_list.push("milk");
|
shopping_list.push("milk");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,12 @@
|
||||||
// This powerful wrapper provides the ability to store a positive integer value.
|
// This powerful wrapper provides the ability to store a positive integer value.
|
||||||
// Rewrite it using generics so that it supports wrapping ANY type.
|
// Rewrite it using generics so that it supports wrapping ANY type.
|
||||||
|
|
||||||
// I AM NOT DONE
|
struct Wrapper<T> {
|
||||||
|
value: T,
|
||||||
struct Wrapper {
|
|
||||||
value: u32,
|
|
||||||
}
|
}
|
||||||
|
// <T> must be both for impl and Wrapper
|
||||||
impl Wrapper {
|
impl<T> Wrapper<T> {
|
||||||
pub fn new(value: u32) -> Self {
|
pub fn new(value: T) -> Self {
|
||||||
Wrapper { value }
|
Wrapper { value }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,15 +10,15 @@
|
||||||
|
|
||||||
// Execute 'rustlings hint generics3' for hints!
|
// Execute 'rustlings hint generics3' for hints!
|
||||||
|
|
||||||
// I AM NOT DONE
|
pub struct ReportCard<T> {
|
||||||
|
pub grade: T,
|
||||||
pub struct ReportCard {
|
|
||||||
pub grade: f32,
|
|
||||||
pub student_name: String,
|
pub student_name: String,
|
||||||
pub student_age: u8,
|
pub student_age: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ReportCard {
|
// <T> must implement std::fmt::Display or no format!() macro
|
||||||
|
// for you
|
||||||
|
impl<T: std::fmt::Display> ReportCard<T> {
|
||||||
pub fn print(&self) -> String {
|
pub fn print(&self) -> String {
|
||||||
format!("{} ({}) - achieved a grade of {}",
|
format!("{} ({}) - achieved a grade of {}",
|
||||||
&self.student_name, &self.student_age, &self.grade)
|
&self.student_name, &self.student_age, &self.grade)
|
||||||
|
@ -46,7 +46,7 @@ mod tests {
|
||||||
fn generate_alphabetic_report_card() {
|
fn generate_alphabetic_report_card() {
|
||||||
// TODO: Make sure to change the grade here after you finish the exercise.
|
// TODO: Make sure to change the grade here after you finish the exercise.
|
||||||
let report_card = ReportCard {
|
let report_card = ReportCard {
|
||||||
grade: 2.1,
|
grade: "A+".to_string(),
|
||||||
student_name: "Gary Plotter".to_string(),
|
student_name: "Gary Plotter".to_string(),
|
||||||
student_age: 11,
|
student_age: 11,
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
### If
|
# If
|
||||||
|
|
||||||
`if`, the most basic type of control flow, is what you'll learn here.
|
`if`, the most basic type of control flow, is what you'll learn here.
|
||||||
|
|
||||||
#### Book Sections
|
## Further information
|
||||||
|
|
||||||
- [Control Flow - if expressions](https://doc.rust-lang.org/book/ch03-05-control-flow.html#if-expressions)
|
- [Control Flow - if expressions](https://doc.rust-lang.org/book/ch03-05-control-flow.html#if-expressions)
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
// if1.rs
|
// if1.rs
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
pub fn bigger(a: i32, b: i32) -> i32 {
|
|
||||||
// Complete this function to return the bigger number!
|
// Complete this function to return the bigger number!
|
||||||
// Do not use:
|
// Do not use:
|
||||||
// - another function call
|
// - another function call
|
||||||
// - additional variables
|
// - additional variables
|
||||||
// Execute `rustlings hint if1` for hints
|
// Execute `rustlings hint if1` for hints
|
||||||
|
pub fn bigger(a: i32, b: i32) -> i32 {
|
||||||
|
if a > b {
|
||||||
|
a
|
||||||
|
} else {
|
||||||
|
b
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't mind this for now :)
|
// Don't mind this for now :)
|
||||||
|
|
|
@ -4,13 +4,14 @@
|
||||||
// Step 2: Get the bar_for_fuzz and default_to_baz tests passing!
|
// Step 2: Get the bar_for_fuzz and default_to_baz tests passing!
|
||||||
// Execute the command `rustlings hint if2` if you want a hint :)
|
// Execute the command `rustlings hint if2` if you want a hint :)
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
pub fn fizz_if_foo(fizzish: &str) -> &str {
|
pub fn fizz_if_foo(fizzish: &str) -> &str {
|
||||||
if fizzish == "fizz" {
|
if fizzish == "fizz" {
|
||||||
"foo"
|
"foo"
|
||||||
|
} else if fizzish == "fuzz" {
|
||||||
|
"bar"
|
||||||
} else {
|
} else {
|
||||||
1
|
"baz"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
### Macros
|
# Macros
|
||||||
|
|
||||||
Rust's macro system is very powerful, but also kind of difficult to wrap your
|
Rust's macro system is very powerful, but also kind of difficult to wrap your
|
||||||
head around. We're not going to teach you how to write your own fully-featured
|
head around. We're not going to teach you how to write your own fully-featured
|
||||||
macros. Instead, we'll show you how to use and create them.
|
macros. Instead, we'll show you how to use and create them.
|
||||||
|
|
||||||
#### Book Sections
|
## 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://danielkeep.github.io/tlborm/book/index.html)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
### Modules
|
# Modules
|
||||||
|
|
||||||
In this section we'll give you an introduction to Rust's module system.
|
In this section we'll give you an introduction to Rust's module system.
|
||||||
|
|
||||||
#### Book Sections
|
## Further information
|
||||||
|
|
||||||
- [The Module System](https://doc.rust-lang.org/book/ch07-02-defining-modules-to-control-scope-and-privacy.html)
|
- [The Module System](https://doc.rust-lang.org/book/ch07-02-defining-modules-to-control-scope-and-privacy.html)
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
// modules1.rs
|
// modules1.rs
|
||||||
// Make me compile! Execute `rustlings hint modules1` for hints :)
|
// Make me compile! Execute `rustlings hint modules1` for hints :)
|
||||||
|
|
||||||
// I AM NOT DONE
|
// `mod` defines a module which can contain functions, structs etc.
|
||||||
|
// by default, its `fn`s only limited within itself, creating "closed
|
||||||
|
// ecosystem". you can make them public with `pub`
|
||||||
|
|
||||||
mod sausage_factory {
|
mod sausage_factory {
|
||||||
fn make_sausage() {
|
pub fn make_sausage() {
|
||||||
println!("sausage!");
|
println!("sausage!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
// modules2.rs
|
// modules2.rs
|
||||||
// Make me compile! Execute `rustlings hint modules2` for hints :)
|
// Make me compile! Execute `rustlings hint modules2` for hints :)
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
mod delicious_snacks {
|
mod delicious_snacks {
|
||||||
use self::fruits::PEAR as fruit;
|
pub use self::fruits::PEAR as fruit;
|
||||||
use self::veggies::CUCUMBER as veggie;
|
pub use self::veggies::CUCUMBER as veggie;
|
||||||
|
|
||||||
mod fruits {
|
mod fruits {
|
||||||
pub const PEAR: &'static str = "Pear";
|
pub const PEAR: &'static str = "Pear";
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
### Move Semantics
|
# Move Semantics
|
||||||
|
|
||||||
These exercises are adapted from [pnkfelix](https://github.com/pnkfelix)'s [Rust Tutorial](https://pnkfelix.github.io/rust-examples-icfp2014/) -- Thank you Felix!!!
|
These exercises are adapted from [pnkfelix](https://github.com/pnkfelix)'s [Rust Tutorial](https://pnkfelix.github.io/rust-examples-icfp2014/) -- Thank you Felix!!!
|
||||||
|
|
||||||
#### Book Sections
|
## Further information
|
||||||
|
|
||||||
For this section, the book links are especially important.
|
For this section, the book links are especially important.
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
// move_semantics1.rs
|
// move_semantics1.rs
|
||||||
// Make me compile! Execute `rustlings hint move_semantics1` for hints :)
|
// Make me compile! Execute `rustlings hint move_semantics1` for hints :)
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let vec0 = Vec::new();
|
let vec0 = Vec::new();
|
||||||
|
|
||||||
let vec1 = fill_vec(vec0);
|
let mut vec1 = fill_vec(vec0);
|
||||||
|
|
||||||
println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
|
println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
|
||||||
|
|
||||||
|
|
|
@ -2,12 +2,10 @@
|
||||||
// Make me compile without changing line 13!
|
// Make me compile without changing line 13!
|
||||||
// Execute `rustlings hint move_semantics2` for hints :)
|
// Execute `rustlings hint move_semantics2` for hints :)
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let vec0 = Vec::new();
|
let vec0 = Vec::new();
|
||||||
|
|
||||||
let mut vec1 = fill_vec(vec0);
|
let mut vec1 = fill_vec(&vec0);
|
||||||
|
|
||||||
// Do not change the following line!
|
// Do not change the following line!
|
||||||
println!("{} has length {} content `{:?}`", "vec0", vec0.len(), vec0);
|
println!("{} has length {} content `{:?}`", "vec0", vec0.len(), vec0);
|
||||||
|
@ -17,8 +15,8 @@ fn main() {
|
||||||
println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
|
println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
|
fn fill_vec(vec: &[i32]) -> Vec<i32> {
|
||||||
let mut vec = vec;
|
let mut vec = vec.to_vec();
|
||||||
|
|
||||||
vec.push(22);
|
vec.push(22);
|
||||||
vec.push(44);
|
vec.push(44);
|
||||||
|
|
|
@ -3,12 +3,10 @@
|
||||||
// (no lines with multiple semicolons necessary!)
|
// (no lines with multiple semicolons necessary!)
|
||||||
// Execute `rustlings hint move_semantics3` for hints :)
|
// Execute `rustlings hint move_semantics3` for hints :)
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let vec0 = Vec::new();
|
let vec0 = Vec::new();
|
||||||
|
|
||||||
let mut vec1 = fill_vec(vec0);
|
let mut vec1 = fill_vec(&vec0);
|
||||||
|
|
||||||
println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
|
println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
|
||||||
|
|
||||||
|
@ -17,7 +15,8 @@ fn main() {
|
||||||
println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
|
println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
|
fn fill_vec(vec: &[i32]) -> Vec<i32> {
|
||||||
|
let mut vec = vec.to_vec();
|
||||||
vec.push(22);
|
vec.push(22);
|
||||||
vec.push(44);
|
vec.push(44);
|
||||||
vec.push(66);
|
vec.push(66);
|
||||||
|
|
|
@ -1,15 +1,14 @@
|
||||||
// move_semantics4.rs
|
// move_semantics4.rs
|
||||||
// Refactor this code so that instead of having `vec0` and creating the vector
|
// Refactor this code so that instead of having `vec0` and creating the vector
|
||||||
// in `fn main`, we instead create it within `fn fill_vec` and transfer the
|
// in `fn main`, we create it within `fn fill_vec` and transfer the
|
||||||
// freshly created vector from fill_vec to its caller.
|
// freshly created vector from fill_vec to its caller.
|
||||||
// Execute `rustlings hint move_semantics4` for hints!
|
// Execute `rustlings hint move_semantics4` for hints!
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let vec0 = Vec::new();
|
// let vec0 = Vec::new();
|
||||||
|
|
||||||
let mut vec1 = fill_vec(vec0);
|
let mut vec1 = fill_vec();
|
||||||
|
|
||||||
println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
|
println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
|
||||||
|
|
||||||
|
@ -20,7 +19,7 @@ fn main() {
|
||||||
|
|
||||||
// `fill_vec()` no longer takes `vec: Vec<i32>` as argument
|
// `fill_vec()` no longer takes `vec: Vec<i32>` as argument
|
||||||
fn fill_vec() -> Vec<i32> {
|
fn fill_vec() -> Vec<i32> {
|
||||||
let mut vec = vec;
|
let mut vec = Vec::new();
|
||||||
|
|
||||||
vec.push(22);
|
vec.push(22);
|
||||||
vec.push(44);
|
vec.push(44);
|
||||||
|
|
|
@ -1,8 +1,17 @@
|
||||||
### Option
|
# Option
|
||||||
|
|
||||||
#### Book Sections
|
Type Option represents an optional value: every Option is either Some and contains a value, or None, and does not.
|
||||||
|
Option types are very common in Rust code, as they have a number of uses:
|
||||||
|
- Initial values
|
||||||
|
- Return values for functions that are not defined over their entire input range (partial functions)
|
||||||
|
- Return value for otherwise reporting simple errors, where None is returned on error
|
||||||
|
- Optional struct fields
|
||||||
|
- Struct fields that can be loaned or "taken"
|
||||||
|
- Optional function arguments
|
||||||
|
- Nullable pointers
|
||||||
|
- Swapping things out of difficult situations
|
||||||
|
|
||||||
To learn about Option<T>, check out these links:
|
## Further Information
|
||||||
|
|
||||||
- [Option Enum Format](https://doc.rust-lang.org/stable/book/ch10-01-syntax.html#in-enum-definitions)
|
- [Option Enum Format](https://doc.rust-lang.org/stable/book/ch10-01-syntax.html#in-enum-definitions)
|
||||||
- [Option Module Documentation](https://doc.rust-lang.org/std/option/)
|
- [Option Module Documentation](https://doc.rust-lang.org/std/option/)
|
||||||
|
|
|
@ -9,15 +9,16 @@ fn print_number(maybe_number: Option<u16>) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
print_number(13);
|
// rustc suggested solutions
|
||||||
print_number(99);
|
print_number(Some(13));
|
||||||
|
print_number(Some(99));
|
||||||
|
|
||||||
let mut numbers: [Option<u16>; 5];
|
let numbers: [Option<u16>; 5];
|
||||||
for iter in 0..5 {
|
for iter in 0..5 {
|
||||||
let number_to_add: u16 = {
|
let number_to_add: u16 = {
|
||||||
((iter * 1235) + 2) / (4 * 16)
|
((iter * 1235) + 2) / (4 * 16)
|
||||||
};
|
};
|
||||||
|
|
||||||
numbers[iter as usize] = number_to_add;
|
numbers[iter as usize] = Some(number_to_add);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,22 +4,22 @@
|
||||||
// I AM NOT DONE
|
// I AM NOT DONE
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let optional_value = Some(String::from("rustlings"));
|
let optional_word = Some(String::from("rustlings"));
|
||||||
// TODO: Make this an if let statement whose value is "Some" type
|
// TODO: Make this an if let statement whose value is "Some" type
|
||||||
value = optional_value {
|
word = optional_word {
|
||||||
println!("the value of optional value is: {}", value);
|
println!("The word is: {}", word);
|
||||||
} else {
|
} else {
|
||||||
println!("The optional value doesn't contain anything!");
|
println!("The optional word doesn't contain anything");
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut optional_values_vec: Vec<Option<i8>> = Vec::new();
|
let mut optional_integers_vec: Vec<Option<i8>> = Vec::new();
|
||||||
for x in 1..10 {
|
for x in 1..10 {
|
||||||
optional_values_vec.push(Some(x));
|
optional_integers_vec.push(Some(x));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
||||||
value = optional_values_vec.pop() {
|
integer = optional_integers_vec.pop() {
|
||||||
println!("current value: {}", value);
|
println!("current value: {}", integer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
### Primitive Types
|
# Primitive Types
|
||||||
|
|
||||||
Rust has a couple of basic types that are directly implemented into the
|
Rust has a couple of basic types that are directly implemented into the
|
||||||
compiler. In this section, we'll go through the most important ones.
|
compiler. In this section, we'll go through the most important ones.
|
||||||
|
|
||||||
#### Book Sections
|
## Further information
|
||||||
|
|
||||||
- [Data Types](https://doc.rust-lang.org/stable/book/ch03-02-data-types.html)
|
- [Data Types](https://doc.rust-lang.org/stable/book/ch03-02-data-types.html)
|
||||||
- [The Slice Type](https://doc.rust-lang.org/stable/book/ch04-03-slices.html)
|
- [The Slice Type](https://doc.rust-lang.org/stable/book/ch04-03-slices.html)
|
||||||
|
|
|
@ -2,8 +2,6 @@
|
||||||
// Fill in the rest of the line that has code missing!
|
// Fill in the rest of the line that has code missing!
|
||||||
// No hints, there's no tricks, just get used to typing these :)
|
// No hints, there's no tricks, just get used to typing these :)
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// Booleans (`bool`)
|
// Booleans (`bool`)
|
||||||
|
|
||||||
|
@ -12,7 +10,7 @@ fn main() {
|
||||||
println!("Good morning!");
|
println!("Good morning!");
|
||||||
}
|
}
|
||||||
|
|
||||||
let // Finish the rest of this line like the example! Or make it be false!
|
let is_evening = true; // Finish the rest of this line like the example! Or make it be false!
|
||||||
if is_evening {
|
if is_evening {
|
||||||
println!("Good evening!");
|
println!("Good evening!");
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,6 @@
|
||||||
// Fill in the rest of the line that has code missing!
|
// Fill in the rest of the line that has code missing!
|
||||||
// No hints, there's no tricks, just get used to typing these :)
|
// No hints, there's no tricks, just get used to typing these :)
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// Characters (`char`)
|
// Characters (`char`)
|
||||||
|
|
||||||
|
@ -16,7 +14,7 @@ fn main() {
|
||||||
println!("Neither alphabetic nor numeric!");
|
println!("Neither alphabetic nor numeric!");
|
||||||
}
|
}
|
||||||
|
|
||||||
let // Finish this line like the example! What's your favorite character?
|
let your_character = 'D'; // Finish this line like the example! What's your favorite character?
|
||||||
// Try a letter, try a number, try a special character, try a character
|
// Try a letter, try a number, try a special character, try a character
|
||||||
// from a different language than your own, try an emoji!
|
// from a different language than your own, try an emoji!
|
||||||
if your_character.is_alphabetic() {
|
if your_character.is_alphabetic() {
|
||||||
|
|
|
@ -2,10 +2,9 @@
|
||||||
// Create an array with at least 100 elements in it where the ??? is.
|
// Create an array with at least 100 elements in it where the ??? is.
|
||||||
// Execute `rustlings hint primitive_types3` for hints!
|
// Execute `rustlings hint primitive_types3` for hints!
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let a = ???
|
let a: [i32; 300] = [0; 300];
|
||||||
|
|
||||||
if a.len() >= 100 {
|
if a.len() >= 100 {
|
||||||
println!("Wow, that's a big array!");
|
println!("Wow, that's a big array!");
|
||||||
|
|
|
@ -2,13 +2,11 @@
|
||||||
// Get a slice out of Array a where the ??? is so that the test passes.
|
// Get a slice out of Array a where the ??? is so that the test passes.
|
||||||
// Execute `rustlings hint primitive_types4` for hints!!
|
// Execute `rustlings hint primitive_types4` for hints!!
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn slice_out_of_array() {
|
fn slice_out_of_array() {
|
||||||
let a = [1, 2, 3, 4, 5];
|
let a = [1, 2, 3, 4, 5];
|
||||||
|
|
||||||
let nice_slice = ???
|
let nice_slice = &a[1..4];
|
||||||
|
|
||||||
assert_eq!([2, 3, 4], nice_slice)
|
assert_eq!([2, 3, 4], nice_slice)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,11 +2,9 @@
|
||||||
// Destructure the `cat` tuple so that the println will work.
|
// Destructure the `cat` tuple so that the println will work.
|
||||||
// Execute `rustlings hint primitive_types5` for hints!
|
// Execute `rustlings hint primitive_types5` for hints!
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let cat = ("Furry McFurson", 3.5);
|
let cat = ("Furry McFurson", 3.5);
|
||||||
let /* your pattern here */ = cat;
|
let (name, age) = cat;
|
||||||
|
|
||||||
println!("{} is {} years old.", name, age);
|
println!("{} is {} years old.", name, age);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,14 +2,11 @@
|
||||||
// Use a tuple index to access the second element of `numbers`.
|
// Use a tuple index to access the second element of `numbers`.
|
||||||
// You can put the expression for the second element where ??? is so that the test passes.
|
// You can put the expression for the second element where ??? is so that the test passes.
|
||||||
// Execute `rustlings hint primitive_types6` for hints!
|
// Execute `rustlings hint primitive_types6` for hints!
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn indexing_tuple() {
|
fn indexing_tuple() {
|
||||||
let numbers = (1, 2, 3);
|
let numbers = (1, 2, 3);
|
||||||
// Replace below ??? with the tuple indexing syntax.
|
// Replace below ??? with the tuple indexing syntax.
|
||||||
let second = ???;
|
let second = numbers.1;
|
||||||
|
|
||||||
assert_eq!(2, second,
|
assert_eq!(2, second,
|
||||||
"This is not the 2nd number in the tuple!")
|
"This is not the 2nd number in the tuple!")
|
||||||
|
|
|
@ -7,10 +7,16 @@
|
||||||
// more than 40 at once, each apple only costs 1! Write a function that calculates
|
// more than 40 at once, each apple only costs 1! Write a function that calculates
|
||||||
// the price of an order of apples given the order amount. No hints this time!
|
// the price of an order of apples given the order amount. No hints this time!
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
// Put your function here!
|
// Put your function here!
|
||||||
// fn ..... {
|
// fn ..... {
|
||||||
|
fn calculate_apple_price(amount: i32) -> i32 {
|
||||||
|
if amount > 40 {
|
||||||
|
1 * amount
|
||||||
|
} else {
|
||||||
|
2 * amount
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Don't modify this function!
|
// Don't modify this function!
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -7,8 +7,6 @@
|
||||||
// you think each value is. That is, add either `string_slice` or `string`
|
// you think each value is. That is, add either `string_slice` or `string`
|
||||||
// before the parentheses on each line. If you're right, it will compile!
|
// before the parentheses on each line. If you're right, it will compile!
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn string_slice(arg: &str) {
|
fn string_slice(arg: &str) {
|
||||||
println!("{}", arg);
|
println!("{}", arg);
|
||||||
}
|
}
|
||||||
|
@ -17,14 +15,14 @@ fn string(arg: String) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
???("blue");
|
string_slice("blue");
|
||||||
???("red".to_string());
|
string("red".to_string());
|
||||||
???(String::from("hi"));
|
string(String::from("hi"));
|
||||||
???("rust is fun!".to_owned());
|
string("rust is fun!".to_owned());
|
||||||
???("nice weather".into());
|
string("nice weather".into());
|
||||||
???(format!("Interpolation {}", "Station"));
|
string(format!("Interpolation {}", "Station"));
|
||||||
???(&String::from("abc")[0..1]);
|
string_slice(&String::from("abc")[0..1]);
|
||||||
???(" hello there ".trim());
|
string_slice(" hello there ".trim());
|
||||||
???("Happy Monday!".to_string().replace("Mon", "Tues"));
|
string("Happy Monday!".to_string().replace("Mon", "Tues"));
|
||||||
???("mY sHiFt KeY iS sTiCkY".to_lowercase());
|
string("mY sHiFt KeY iS sTiCkY".to_lowercase());
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn returns_twice_of_negative_numbers() {
|
fn returns_twice_of_negative_numbers() {
|
||||||
// TODO write an assert for `times_two(-4)`
|
// TODO replace unimplemented!() with an assert for `times_two(-4)`
|
||||||
|
unimplemented!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
For the Box exercise check out the chapter [Using Box to Point to Data on the Heap](https://doc.rust-lang.org/book/ch15-01-box.html).
|
# Standard library types
|
||||||
|
|
||||||
For the Arc exercise check out the chapter [Shared-State Concurrency](https://doc.rust-lang.org/book/ch16-03-shared-state.html) of the Rust Book.
|
This section will teach you about Box, Shared-State Concurrency and Iterators.
|
||||||
|
|
||||||
For the Iterator exercise check out the chapters [Iterator](https://doc.rust-lang.org/book/ch13-02-iterators.html) of the Rust Book and the [Iterator documentation](https://doc.rust-lang.org/stable/std/iter/).
|
## Further information
|
||||||
|
|
||||||
|
- [Using Box to Point to Data on the Heap](https://doc.rust-lang.org/book/ch15-01-box.html)
|
||||||
|
- [Shared-State Concurrency](https://doc.rust-lang.org/book/ch16-03-shared-state.html)
|
||||||
|
- [Iterator](https://doc.rust-lang.org/book/ch13-02-iterators.html)
|
||||||
|
- [Iterator documentation](https://doc.rust-lang.org/stable/std/iter/)
|
||||||
|
|
|
@ -1,7 +1,21 @@
|
||||||
// arc1.rs
|
// arc1.rs
|
||||||
|
// In this exercise, we are given a Vec of u32 called "numbers" with values ranging
|
||||||
|
// from 0 to 99 -- [ 0, 1, 2, ..., 98, 99 ]
|
||||||
|
// We would like to use this set of numbers within 8 different threads simultaneously.
|
||||||
|
// Each thread is going to get the sum of every eighth value, with an offset.
|
||||||
|
// The first thread (offset 0), will sum 0, 8, 16, ...
|
||||||
|
// The second thread (offset 1), will sum 1, 9, 17, ...
|
||||||
|
// The third thread (offset 2), will sum 2, 10, 18, ...
|
||||||
|
// ...
|
||||||
|
// The eighth thread (offset 7), will sum 7, 15, 23, ...
|
||||||
|
|
||||||
|
// Because we are using threads, our values need to be thread-safe. Therefore,
|
||||||
|
// we are using Arc. We need to make a change in each of the two TODOs.
|
||||||
|
|
||||||
|
|
||||||
// Make this code compile by filling in a value for `shared_numbers` where the
|
// Make this code compile by filling in a value for `shared_numbers` where the
|
||||||
// TODO comment is and create an initial binding for `child_numbers`
|
// first TODO comment is, and create an initial binding for `child_numbers`
|
||||||
// somewhere. Try not to create any copies of the `numbers` Vec!
|
// where the second TODO comment is. Try not to create any copies of the `numbers` Vec!
|
||||||
// Execute `rustlings hint arc1` for hints :)
|
// Execute `rustlings hint arc1` for hints :)
|
||||||
|
|
||||||
// I AM NOT DONE
|
// I AM NOT DONE
|
||||||
|
@ -16,6 +30,7 @@ fn main() {
|
||||||
let mut joinhandles = Vec::new();
|
let mut joinhandles = Vec::new();
|
||||||
|
|
||||||
for offset in 0..8 {
|
for offset in 0..8 {
|
||||||
|
let child_numbers = // TODO
|
||||||
joinhandles.push(thread::spawn(move || {
|
joinhandles.push(thread::spawn(move || {
|
||||||
let mut i = offset;
|
let mut i = offset;
|
||||||
let mut sum = 0;
|
let mut sum = 0;
|
||||||
|
|
|
@ -1,28 +1,41 @@
|
||||||
// iterators2.rs
|
// iterators2.rs
|
||||||
// In this module, you'll learn some of the unique advantages that iterators can offer.
|
// In this exercise, you'll learn some of the unique advantages that iterators
|
||||||
// Step 1. Complete the `capitalize_first` function to pass the first two cases.
|
// can offer. Follow the steps to complete the exercise.
|
||||||
// Step 2. Apply the `capitalize_first` function to a vector of strings.
|
|
||||||
// Ensure that it returns a vector of strings as well.
|
|
||||||
// Step 3. Apply the `capitalize_first` function again to a list.
|
|
||||||
// Try to ensure it returns a single string.
|
|
||||||
// As always, there are hints if you execute `rustlings hint iterators2`!
|
// As always, there are hints if you execute `rustlings hint iterators2`!
|
||||||
|
|
||||||
// I AM NOT DONE
|
// I AM NOT DONE
|
||||||
|
|
||||||
|
// Step 1.
|
||||||
|
// Complete the `capitalize_first` function.
|
||||||
|
// "hello" -> "Hello"
|
||||||
pub fn capitalize_first(input: &str) -> String {
|
pub fn capitalize_first(input: &str) -> String {
|
||||||
let mut c = input.chars();
|
let mut c = input.chars();
|
||||||
match c.next() {
|
match c.next() {
|
||||||
None => String::new(),
|
None => String::new(),
|
||||||
Some(first) => first.collect::<String>() + c.as_str(),
|
Some(first) => ???,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Step 2.
|
||||||
|
// Apply the `capitalize_first` function to a slice of string slices.
|
||||||
|
// Return a vector of strings.
|
||||||
|
// ["hello", "world"] -> ["Hello", "World"]
|
||||||
|
pub fn capitalize_words_vector(words: &[&str]) -> Vec<String> {
|
||||||
|
vec![]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 3.
|
||||||
|
// Apply the `capitalize_first` function again to a slice of string slices.
|
||||||
|
// Return a single string.
|
||||||
|
// ["hello", " ", "world"] -> "Hello World"
|
||||||
|
pub fn capitalize_words_string(words: &[&str]) -> String {
|
||||||
|
String::new()
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
// Step 1.
|
|
||||||
// Tests that verify your `capitalize_first` function implementation
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_success() {
|
fn test_success() {
|
||||||
assert_eq!(capitalize_first("hello"), "Hello");
|
assert_eq!(capitalize_first("hello"), "Hello");
|
||||||
|
@ -33,18 +46,15 @@ mod tests {
|
||||||
assert_eq!(capitalize_first(""), "");
|
assert_eq!(capitalize_first(""), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 2.
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_iterate_string_vec() {
|
fn test_iterate_string_vec() {
|
||||||
let words = vec!["hello", "world"];
|
let words = vec!["hello", "world"];
|
||||||
let capitalized_words: Vec<String> = // TODO
|
assert_eq!(capitalize_words_vector(&words), ["Hello", "World"]);
|
||||||
assert_eq!(capitalized_words, ["Hello", "World"]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_iterate_into_string() {
|
fn test_iterate_into_string() {
|
||||||
let words = vec!["hello", " ", "world"];
|
let words = vec!["hello", " ", "world"];
|
||||||
let capitalized_words = // TODO
|
assert_eq!(capitalize_words_string(&words), "Hello World");
|
||||||
assert_eq!(capitalized_words, "Hello World");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
// iterators3.rs
|
// iterators3.rs
|
||||||
// This is a bigger exercise than most of the others! You can do it!
|
// This is a bigger exercise than most of the others! You can do it!
|
||||||
// Here is your mission, should you choose to accept it:
|
// Here is your mission, should you choose to accept it:
|
||||||
// 1. Complete the divide function to get the first four tests to pass
|
// 1. Complete the divide function to get the first four tests to pass.
|
||||||
// 2. Uncomment the last two tests and get them to pass by filling in
|
// 2. Get the remaining tests to pass by completing the result_with_list and
|
||||||
// values for `x` using `division_results`.
|
// list_of_results functions.
|
||||||
// Execute `rustlings hint iterators3` to get some hints!
|
// Execute `rustlings hint iterators3` to get some hints!
|
||||||
// Have fun :-)
|
|
||||||
|
|
||||||
// I AM NOT DONE
|
// I AM NOT DONE
|
||||||
|
|
||||||
|
@ -21,16 +20,28 @@ pub struct NotDivisibleError {
|
||||||
divisor: i32,
|
divisor: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function should calculate `a` divided by `b` if `a` is
|
// Calculate `a` divided by `b` if `a` is evenly divisible by `b`.
|
||||||
// evenly divisible by b.
|
// Otherwise, return a suitable error.
|
||||||
// Otherwise, it should return a suitable error.
|
|
||||||
pub fn divide(a: i32, b: i32) -> Result<i32, DivisionError> {}
|
pub fn divide(a: i32, b: i32) -> Result<i32, DivisionError> {}
|
||||||
|
|
||||||
|
// Complete the function and return a value of the correct type so the test passes.
|
||||||
|
// Desired output: Ok([1, 11, 1426, 3])
|
||||||
|
fn result_with_list() -> () {
|
||||||
|
let numbers = vec![27, 297, 38502, 81];
|
||||||
|
let division_results = numbers.into_iter().map(|n| divide(n, 27));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Complete the function and return a value of the correct type so the test passes.
|
||||||
|
// Desired output: [Ok(1), Ok(11), Ok(1426), Ok(3)]
|
||||||
|
fn list_of_results() -> () {
|
||||||
|
let numbers = vec![27, 297, 38502, 81];
|
||||||
|
let division_results = numbers.into_iter().map(|n| divide(n, 27));
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
// Tests that verify your `divide` function implementation
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_success() {
|
fn test_success() {
|
||||||
assert_eq!(divide(81, 9), Ok(9));
|
assert_eq!(divide(81, 9), Ok(9));
|
||||||
|
@ -57,22 +68,16 @@ mod tests {
|
||||||
assert_eq!(divide(0, 81), Ok(0));
|
assert_eq!(divide(0, 81), Ok(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Iterator exercises using your `divide` function
|
|
||||||
/*
|
|
||||||
#[test]
|
#[test]
|
||||||
fn result_with_list() {
|
fn test_result_with_list() {
|
||||||
let numbers = vec![27, 297, 38502, 81];
|
assert_eq!(format!("{:?}", result_with_list()), "Ok([1, 11, 1426, 3])");
|
||||||
let division_results = numbers.into_iter().map(|n| divide(n, 27));
|
|
||||||
let x //... Fill in here!
|
|
||||||
assert_eq!(format!("{:?}", x), "Ok([1, 11, 1426, 3])");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn list_of_results() {
|
fn test_list_of_results() {
|
||||||
let numbers = vec![27, 297, 38502, 81];
|
assert_eq!(
|
||||||
let division_results = numbers.into_iter().map(|n| divide(n, 27));
|
format!("{:?}", list_of_results()),
|
||||||
let x //... Fill in here!
|
"[Ok(1), Ok(11), Ok(1426), Ok(3)]"
|
||||||
assert_eq!(format!("{:?}", x), "[Ok(1), Ok(11), Ok(1426), Ok(3)]");
|
);
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
124
exercises/standard_library_types/iterators5.rs
Normal file
124
exercises/standard_library_types/iterators5.rs
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
// iterators5.rs
|
||||||
|
|
||||||
|
// Let's define a simple model to track Rustlings exercise progress. Progress
|
||||||
|
// will be modelled using a hash map. The name of the exercise is the key and
|
||||||
|
// the progress is the value. Two counting functions were created to count the
|
||||||
|
// number of exercises with a given progress. These counting functions use
|
||||||
|
// imperative style for loops. Recreate this counting functionality using
|
||||||
|
// iterators. Only the two iterator methods (count_iterator and
|
||||||
|
// count_collection_iterator) need to be modified.
|
||||||
|
// Execute `rustlings hint
|
||||||
|
// iterators5` for hints.
|
||||||
|
//
|
||||||
|
// Make the code compile and the tests pass.
|
||||||
|
|
||||||
|
// I AM NOT DONE
|
||||||
|
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
#[derive(PartialEq, Eq)]
|
||||||
|
enum Progress {
|
||||||
|
None,
|
||||||
|
Some,
|
||||||
|
Complete,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn count_for(map: &HashMap<String, Progress>, value: Progress) -> usize {
|
||||||
|
let mut count = 0;
|
||||||
|
for val in map.values() {
|
||||||
|
if val == &value {
|
||||||
|
count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
count
|
||||||
|
}
|
||||||
|
|
||||||
|
fn count_iterator(map: &HashMap<String, Progress>, value: Progress) -> usize {
|
||||||
|
// map is a hashmap with String keys and Progress values.
|
||||||
|
// map = { "variables1": Complete, "from_str": None, ... }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn count_collection_for(collection: &[HashMap<String, Progress>], value: Progress) -> usize {
|
||||||
|
let mut count = 0;
|
||||||
|
for map in collection {
|
||||||
|
for val in map.values() {
|
||||||
|
if val == &value {
|
||||||
|
count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
count
|
||||||
|
}
|
||||||
|
|
||||||
|
fn count_collection_iterator(collection: &[HashMap<String, Progress>], value: Progress) -> usize {
|
||||||
|
// collection is a slice of hashmaps.
|
||||||
|
// collection = [{ "variables1": Complete, "from_str": None, ... },
|
||||||
|
// { "variables2": Complete, ... }, ... ]
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn count_complete() {
|
||||||
|
let map = get_map();
|
||||||
|
assert_eq!(3, count_iterator(&map, Progress::Complete));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn count_equals_for() {
|
||||||
|
let map = get_map();
|
||||||
|
assert_eq!(
|
||||||
|
count_for(&map, Progress::Complete),
|
||||||
|
count_iterator(&map, Progress::Complete)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn count_collection_complete() {
|
||||||
|
let collection = get_vec_map();
|
||||||
|
assert_eq!(
|
||||||
|
6,
|
||||||
|
count_collection_iterator(&collection, Progress::Complete)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn count_collection_equals_for() {
|
||||||
|
let collection = get_vec_map();
|
||||||
|
assert_eq!(
|
||||||
|
count_collection_for(&collection, Progress::Complete),
|
||||||
|
count_collection_iterator(&collection, Progress::Complete)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_map() -> HashMap<String, Progress> {
|
||||||
|
use Progress::*;
|
||||||
|
|
||||||
|
let mut map = HashMap::new();
|
||||||
|
map.insert(String::from("variables1"), Complete);
|
||||||
|
map.insert(String::from("functions1"), Complete);
|
||||||
|
map.insert(String::from("hashmap1"), Complete);
|
||||||
|
map.insert(String::from("arc1"), Some);
|
||||||
|
map.insert(String::from("as_ref_mut"), None);
|
||||||
|
map.insert(String::from("from_str"), None);
|
||||||
|
|
||||||
|
map
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_vec_map() -> Vec<HashMap<String, Progress>> {
|
||||||
|
use Progress::*;
|
||||||
|
|
||||||
|
let map = get_map();
|
||||||
|
|
||||||
|
let mut other = HashMap::new();
|
||||||
|
other.insert(String::from("variables2"), Complete);
|
||||||
|
other.insert(String::from("functions2"), Complete);
|
||||||
|
other.insert(String::from("if1"), Complete);
|
||||||
|
other.insert(String::from("from_into"), None);
|
||||||
|
other.insert(String::from("try_from_into"), None);
|
||||||
|
|
||||||
|
vec![map, other]
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,9 +1,9 @@
|
||||||
### Strings
|
# Strings
|
||||||
|
|
||||||
Rust has two string types, a string slice (`&str`) and an owned string (`String`).
|
Rust has two string types, a string slice (`&str`) and an owned string (`String`).
|
||||||
We're not going to dictate when you should use which one, but we'll show you how
|
We're not going to dictate when you should use which one, but we'll show you how
|
||||||
to identify and create them, as well as use them.
|
to identify and create them, as well as use them.
|
||||||
|
|
||||||
#### Book Sections
|
## Further information
|
||||||
|
|
||||||
- [Strings](https://doc.rust-lang.org/book/ch08-02-strings.html)
|
- [Strings](https://doc.rust-lang.org/book/ch08-02-strings.html)
|
||||||
|
|
|
@ -2,13 +2,13 @@
|
||||||
// Make me compile without changing the function signature!
|
// Make me compile without changing the function signature!
|
||||||
// Execute `rustlings hint strings1` for hints ;)
|
// Execute `rustlings hint strings1` for hints ;)
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let answer = current_favorite_color();
|
let answer = current_favorite_color();
|
||||||
println!("My current favorite color is {}", answer);
|
println!("My current favorite color is {}", answer);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn current_favorite_color() -> String {
|
fn current_favorite_color() -> String {
|
||||||
"blue"
|
// .to_string uses fmt trait
|
||||||
|
// .to_owned works too
|
||||||
|
"blue".to_owned()
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,6 @@
|
||||||
// Make me compile without changing the function signature!
|
// Make me compile without changing the function signature!
|
||||||
// Execute `rustlings hint strings2` for hints :)
|
// Execute `rustlings hint strings2` for hints :)
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let word = String::from("green"); // Try not changing this line :)
|
let word = String::from("green"); // Try not changing this line :)
|
||||||
if is_a_color_word(word) {
|
if is_a_color_word(word) {
|
||||||
|
@ -13,6 +11,6 @@ fn main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_a_color_word(attempt: &str) -> bool {
|
fn is_a_color_word(attempt: String) -> bool {
|
||||||
attempt == "green" || attempt == "blue" || attempt == "red"
|
attempt == "green" || attempt == "blue" || attempt == "red"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
### Structs
|
# Structs
|
||||||
|
|
||||||
Rust has three struct types: a classic c struct, a tuple struct, and a unit struct.
|
Rust has three struct types: a classic C struct, a tuple struct, and a unit struct.
|
||||||
|
|
||||||
#### Book Sections
|
## Further information
|
||||||
|
|
||||||
- [Structures](https://doc.rust-lang.org/book/ch05-01-defining-structs.html)
|
- [Structures](https://doc.rust-lang.org/book/ch05-01-defining-structs.html)
|
||||||
|
- [Method Syntax](https://doc.rust-lang.org/book/ch05-03-method-syntax.html)
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
// structs1.rs
|
// structs1.rs
|
||||||
// Address all the TODOs to make the tests pass!
|
// Address all the TODOs to make the tests pass!
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
struct ColorClassicStruct {
|
struct ColorClassicStruct {
|
||||||
// TODO: Something goes here
|
name: String,
|
||||||
|
hex: String
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ColorTupleStruct(/* TODO: Something goes here */);
|
struct ColorTupleStruct(String, String);
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct UnitStruct;
|
struct UnitStruct;
|
||||||
|
@ -19,8 +18,10 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn classic_c_structs() {
|
fn classic_c_structs() {
|
||||||
// TODO: Instantiate a classic c struct!
|
// TODO: Instantiate a classic c struct!
|
||||||
// let green =
|
let green = ColorClassicStruct {
|
||||||
|
name: String::from("green"),
|
||||||
|
hex: String::from("#00FF00")
|
||||||
|
};
|
||||||
assert_eq!(green.name, "green");
|
assert_eq!(green.name, "green");
|
||||||
assert_eq!(green.hex, "#00FF00");
|
assert_eq!(green.hex, "#00FF00");
|
||||||
}
|
}
|
||||||
|
@ -28,7 +29,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn tuple_structs() {
|
fn tuple_structs() {
|
||||||
// TODO: Instantiate a tuple struct!
|
// TODO: Instantiate a tuple struct!
|
||||||
// let green =
|
let green = ColorTupleStruct("green".to_string(),"#00FF00".to_string());
|
||||||
|
|
||||||
assert_eq!(green.0, "green");
|
assert_eq!(green.0, "green");
|
||||||
assert_eq!(green.1, "#00FF00");
|
assert_eq!(green.1, "#00FF00");
|
||||||
|
@ -37,7 +38,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn unit_structs() {
|
fn unit_structs() {
|
||||||
// TODO: Instantiate a unit struct!
|
// TODO: Instantiate a unit struct!
|
||||||
// let unit_struct =
|
let unit_struct = UnitStruct;
|
||||||
let message = format!("{:?}s are fun!", unit_struct);
|
let message = format!("{:?}s are fun!", unit_struct);
|
||||||
|
|
||||||
assert_eq!(message, "UnitStructs are fun!");
|
assert_eq!(message, "UnitStructs are fun!");
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
// structs2.rs
|
// structs2.rs
|
||||||
// Address all the TODOs to make the tests pass!
|
// Address all the TODOs to make the tests pass!
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Order {
|
struct Order {
|
||||||
name: String,
|
name: String,
|
||||||
|
@ -34,7 +32,15 @@ mod tests {
|
||||||
fn your_order() {
|
fn your_order() {
|
||||||
let order_template = create_order_template();
|
let order_template = create_order_template();
|
||||||
// TODO: Create your own order using the update syntax and template above!
|
// TODO: Create your own order using the update syntax and template above!
|
||||||
// let your_order =
|
let your_order = Order {
|
||||||
|
name: String::from("Hacker in Rust"),
|
||||||
|
year: 2019,
|
||||||
|
made_by_phone: false,
|
||||||
|
made_by_mobile: false,
|
||||||
|
made_by_email: true,
|
||||||
|
item_number: 123,
|
||||||
|
count: 1,
|
||||||
|
};
|
||||||
assert_eq!(your_order.name, "Hacker in Rust");
|
assert_eq!(your_order.name, "Hacker in Rust");
|
||||||
assert_eq!(your_order.year, order_template.year);
|
assert_eq!(your_order.year, order_template.year);
|
||||||
assert_eq!(your_order.made_by_phone, order_template.made_by_phone);
|
assert_eq!(your_order.made_by_phone, order_template.made_by_phone);
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
// structs3.rs
|
// structs3.rs
|
||||||
// Structs contain more than simply some data, they can also have logic, in this
|
// Structs contain data, but can also have logic. In this exercise we have
|
||||||
// exercise we have defined the Package struct and we want to test some logic attached to it,
|
// defined the Package struct and we want to test some logic attached to it.
|
||||||
// make the code compile and the tests pass! If you have issues execute `rustlings hint structs3`
|
// Make the code compile and the tests pass!
|
||||||
|
// If you have issues execute `rustlings hint structs3`
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Package {
|
struct Package {
|
||||||
|
@ -15,7 +15,7 @@ struct Package {
|
||||||
impl Package {
|
impl Package {
|
||||||
fn new(sender_country: String, recipient_country: String, weight_in_grams: i32) -> Package {
|
fn new(sender_country: String, recipient_country: String, weight_in_grams: i32) -> Package {
|
||||||
if weight_in_grams <= 0 {
|
if weight_in_grams <= 0 {
|
||||||
// Something goes here...
|
panic!("Weight is in negative value.");
|
||||||
} else {
|
} else {
|
||||||
return Package {
|
return Package {
|
||||||
sender_country,
|
sender_country,
|
||||||
|
@ -25,12 +25,20 @@ impl Package {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_international(&self) -> ??? {
|
fn is_international(&self) -> bool {
|
||||||
// Something goes here...
|
if self.sender_country != self.recipient_country {
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_fees(&self, cents_per_gram: i32) -> ??? {
|
fn get_fees(&self, cents_per_gram: i32) -> i32 {
|
||||||
// Something goes here...
|
if cents_per_gram <= 0 {
|
||||||
|
panic!("We don't pay people, do we?");
|
||||||
|
} else {
|
||||||
|
cents_per_gram * self.weight_in_grams
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,12 +65,22 @@ mod tests {
|
||||||
assert!(package.is_international());
|
assert!(package.is_international());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn create_local_package() {
|
||||||
|
let sender_country = String::from("Canada");
|
||||||
|
let recipient_country = sender_country.clone();
|
||||||
|
|
||||||
|
let package = Package::new(sender_country, recipient_country, 1200);
|
||||||
|
|
||||||
|
assert!(!package.is_international());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn calculate_transport_fees() {
|
fn calculate_transport_fees() {
|
||||||
let sender_country = String::from("Spain");
|
let sender_country = String::from("Spain");
|
||||||
let recipient_country = String::from("Spain");
|
let recipient_country = String::from("Spain");
|
||||||
|
|
||||||
let cents_per_gram = ???;
|
let cents_per_gram = 3;
|
||||||
|
|
||||||
let package = Package::new(sender_country, recipient_country, 1500);
|
let package = Package::new(sender_country, recipient_country, 1500);
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
### Tests
|
# Tests
|
||||||
|
|
||||||
Going out of order from the book to cover tests -- many of the following exercises will ask you to make tests pass!
|
Going out of order from the book to cover tests -- many of the following exercises will ask you to make tests pass!
|
||||||
|
|
||||||
#### Book Sections
|
## Further information
|
||||||
|
|
||||||
- [Writing Tests](https://doc.rust-lang.org/book/ch11-01-writing-tests.html)
|
- [Writing Tests](https://doc.rust-lang.org/book/ch11-01-writing-tests.html)
|
||||||
|
|
|
@ -1 +1,9 @@
|
||||||
For this exercise check out the [Dining Philosophers example](https://doc.rust-lang.org/1.4.0/book/dining-philosophers.html) and the chapter [Concurrency](https://doc.rust-lang.org/book/ch16-01-threads.html) of the Rust Book.
|
# Threads
|
||||||
|
|
||||||
|
In most current operating systems, an executed program’s code is run in a process, and the operating system manages multiple processes at once.
|
||||||
|
Within your program, you can also have independent parts that run simultaneously. The features that run these independent parts are called threads.
|
||||||
|
|
||||||
|
## Further information
|
||||||
|
|
||||||
|
- [Dining Philosophers example](https://doc.rust-lang.org/1.4.0/book/dining-philosophers.html)
|
||||||
|
- [Using Threads to Run Code Simultaneously](https://doc.rust-lang.org/book/ch16-01-threads.html)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
### Traits
|
# Traits
|
||||||
|
|
||||||
A trait is a collection of methods.
|
A trait is a collection of methods.
|
||||||
|
|
||||||
|
@ -7,14 +7,13 @@ Data types can implement traits. To do so, the methods making up the trait are d
|
||||||
In this way, traits are somewhat similar to Java interfaces and C++ abstract classes.
|
In this way, traits are somewhat similar to Java interfaces and C++ abstract classes.
|
||||||
|
|
||||||
Some additional common Rust traits include:
|
Some additional common Rust traits include:
|
||||||
|
- `Clone` (the `clone` method)
|
||||||
+ `Clone` (the `clone` method),
|
- `Display` (which allows formatted display via `{}`)
|
||||||
+ `Display` (which allows formatted display via `{}`), and
|
- `Debug` (which allows formatted display via `{:?}`)
|
||||||
+ `Debug` (which allows formatted display via `{:?}`).
|
|
||||||
|
|
||||||
Because traits indicate shared behavior between data types, they are useful when writing generics.
|
Because traits indicate shared behavior between data types, they are useful when writing generics.
|
||||||
|
|
||||||
|
|
||||||
#### Book Sections
|
## Further information
|
||||||
|
|
||||||
- [Traits](https://doc.rust-lang.org/book/ch10-02-traits.html)
|
- [Traits](https://doc.rust-lang.org/book/ch10-02-traits.html)
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
### Variables
|
# Variables
|
||||||
|
|
||||||
Here you'll learn about simple variables.
|
In Rust, variables are immutable by default.
|
||||||
|
When a variable is immutable, once a value is bound to a name, you can’t change that value.
|
||||||
|
You can make them mutable by adding mut in front of the variable name.
|
||||||
|
|
||||||
#### Book Sections
|
## Further information
|
||||||
|
|
||||||
- [Variables and Mutability](https://doc.rust-lang.org/book/ch03-01-variables-and-mutability.html)
|
- [Variables and Mutability](https://doc.rust-lang.org/book/ch03-01-variables-and-mutability.html)
|
||||||
|
|
|
@ -6,9 +6,7 @@
|
||||||
// even after you already figured it out. If you got everything working and
|
// even after you already figured it out. If you got everything working and
|
||||||
// feel ready for the next exercise, remove the `I AM NOT DONE` comment below.
|
// feel ready for the next exercise, remove the `I AM NOT DONE` comment below.
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
x = 5;
|
let x = 5;
|
||||||
println!("x has the value {}", x);
|
println!("x has the value {}", x);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
// variables2.rs
|
// variables2.rs
|
||||||
// Make me compile! Execute the command `rustlings hint variables2` if you want a hint :)
|
// Make me compile! Execute the command `rustlings hint variables2` if you want a hint :)
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let x;
|
let x = 10;
|
||||||
if x == 10 {
|
if x == 10 {
|
||||||
println!("Ten!");
|
println!("Ten!");
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
// variables3.rs
|
// variables3.rs
|
||||||
// Make me compile! Execute the command `rustlings hint variables3` if you want a hint :)
|
// Make me compile! Execute the command `rustlings hint variables3` if you want a hint :)
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let x = 3;
|
let mut x = 3;
|
||||||
println!("Number {}", x);
|
println!("Number {}", x);
|
||||||
x = 5; // don't change this line
|
x = 5; // don't change this line
|
||||||
println!("Number {}", x);
|
println!("Number {}", x);
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
// variables4.rs
|
// variables4.rs
|
||||||
// Make me compile! Execute the command `rustlings hint variables4` if you want a hint :)
|
// Make me compile! Execute the command `rustlings hint variables4` if you want a hint :)
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let x: i32;
|
let mut x: i32;
|
||||||
|
x = 512;
|
||||||
println!("Number {}", x);
|
println!("Number {}", x);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
// variables5.rs
|
// variables5.rs
|
||||||
// Make me compile! Execute the command `rustlings hint variables5` if you want a hint :)
|
// Make me compile! Execute the command `rustlings hint variables5` if you want a hint :)
|
||||||
|
|
||||||
// I AM NOT DONE
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let number = "T-H-R-E-E";
|
let number = "T-H-R-E-E";
|
||||||
println!("Spell a Number : {}", number);
|
println!("Spell a Number : {}", number);
|
||||||
number = 3;
|
let number = 3;
|
||||||
println!("Number plus two is : {}", number + 2);
|
println!("Number plus two is : {}", number + 2);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
// variables6.rs
|
// variables6.rs
|
||||||
// Make me compile! Execute the command `rustlings hint variables6` if you want a hint :)
|
// Make me compile! Execute the command `rustlings hint variables6` if you want a hint :)
|
||||||
|
|
||||||
// I AM NOT DONE
|
// consts have to have strict data type definition
|
||||||
|
// otherwise they won't work
|
||||||
const NUMBER = 3;
|
const NUMBER: i32 = 3;
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("Number {}", NUMBER);
|
println!("Number {}", NUMBER);
|
||||||
}
|
}
|
||||||
|
|
206
info.toml
206
info.toml
|
@ -210,6 +210,21 @@ So the end goal is to:
|
||||||
- since we're not creating a new vec in `main` anymore, we need to create
|
- since we're not creating a new vec in `main` anymore, we need to create
|
||||||
a new vec in `fill_vec`, similarly to the way we did in `main`"""
|
a new vec in `fill_vec`, similarly to the way we did in `main`"""
|
||||||
|
|
||||||
|
[[exercises]]
|
||||||
|
name = "move_semantics5"
|
||||||
|
path = "exercises/move_semantics/move_semantics5.rs"
|
||||||
|
mode = "compile"
|
||||||
|
hint = """
|
||||||
|
Carefully reason about the range in which each mutable reference is in
|
||||||
|
vogue. Does it help to update the value of referent (x) immediately after
|
||||||
|
the mutable reference is taken? Read more about 'Mutable References'
|
||||||
|
in the book's section References and Borrowing':
|
||||||
|
https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html#mutable-references.
|
||||||
|
|
||||||
|
Additional hint:
|
||||||
|
If you can't add, change, or remove any statements in `main()`, can you
|
||||||
|
reorder them in a way that lets the program compile?"""
|
||||||
|
|
||||||
# PRIMITIVE TYPES
|
# PRIMITIVE TYPES
|
||||||
|
|
||||||
[[exercises]]
|
[[exercises]]
|
||||||
|
@ -284,7 +299,7 @@ hint = """
|
||||||
Rust has more than one type of struct. Three actually, all variants are used to package related data together.
|
Rust has more than one type of struct. Three actually, all variants are used to package related data together.
|
||||||
There are normal (or classic) structs. These are named collections of related data stored in fields.
|
There are normal (or classic) structs. These are named collections of related data stored in fields.
|
||||||
Tuple structs are basically just named tuples.
|
Tuple structs are basically just named tuples.
|
||||||
Finally, Unit structs. These don't have and fields and are useful for generics.
|
Finally, Unit structs. These don't have any fields and are useful for generics.
|
||||||
|
|
||||||
In this exercise you need to complete and implement one of each kind.
|
In this exercise you need to complete and implement one of each kind.
|
||||||
Read more about structs in The Book: https://doc.rust-lang.org/book/ch05-01-defining-structs.html"""
|
Read more about structs in The Book: https://doc.rust-lang.org/book/ch05-01-defining-structs.html"""
|
||||||
|
@ -295,7 +310,7 @@ path = "exercises/structs/structs2.rs"
|
||||||
mode = "test"
|
mode = "test"
|
||||||
hint = """
|
hint = """
|
||||||
Creating instances of structs is easy, all you need to do is assign some values to its fields.
|
Creating instances of structs is easy, all you need to do is assign some values to its fields.
|
||||||
There is however some shortcuts that can be taken when instantiating structs.
|
There are however some shortcuts that can be taken when instantiating structs.
|
||||||
Have a look in The Book, to find out more: https://doc.rust-lang.org/stable/book/ch05-01-defining-structs.html#creating-instances-from-other-instances-with-struct-update-syntax"""
|
Have a look in The Book, to find out more: https://doc.rust-lang.org/stable/book/ch05-01-defining-structs.html#creating-instances-from-other-instances-with-struct-update-syntax"""
|
||||||
|
|
||||||
[[exercises]]
|
[[exercises]]
|
||||||
|
@ -359,7 +374,7 @@ each constant."""
|
||||||
# COLLECTIONS
|
# COLLECTIONS
|
||||||
|
|
||||||
[[exercises]]
|
[[exercises]]
|
||||||
name = "collections1"
|
name = "vec1"
|
||||||
path = "exercises/collections/vec1.rs"
|
path = "exercises/collections/vec1.rs"
|
||||||
mode = "test"
|
mode = "test"
|
||||||
hint = """
|
hint = """
|
||||||
|
@ -373,7 +388,7 @@ of the Rust book to learn more.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
[[exercises]]
|
[[exercises]]
|
||||||
name = "collections2"
|
name = "vec2"
|
||||||
path = "exercises/collections/vec2.rs"
|
path = "exercises/collections/vec2.rs"
|
||||||
mode = "test"
|
mode = "test"
|
||||||
hint = """
|
hint = """
|
||||||
|
@ -383,7 +398,7 @@ Hint 2: Check the suggestion from the compiler error ;)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
[[exercises]]
|
[[exercises]]
|
||||||
name = "collections3"
|
name = "hashmap1"
|
||||||
path = "exercises/collections/hashmap1.rs"
|
path = "exercises/collections/hashmap1.rs"
|
||||||
mode = "test"
|
mode = "test"
|
||||||
hint = """
|
hint = """
|
||||||
|
@ -394,7 +409,7 @@ Hint 2: Number of fruits should be at least 5. And you have to put
|
||||||
"""
|
"""
|
||||||
|
|
||||||
[[exercises]]
|
[[exercises]]
|
||||||
name = "collections4"
|
name = "hashmap2"
|
||||||
path = "exercises/collections/hashmap2.rs"
|
path = "exercises/collections/hashmap2.rs"
|
||||||
mode = "test"
|
mode = "test"
|
||||||
hint = """
|
hint = """
|
||||||
|
@ -470,47 +485,66 @@ and give it a try!"""
|
||||||
[[exercises]]
|
[[exercises]]
|
||||||
name = "errors3"
|
name = "errors3"
|
||||||
path = "exercises/error_handling/errors3.rs"
|
path = "exercises/error_handling/errors3.rs"
|
||||||
mode = "test"
|
mode = "compile"
|
||||||
hint = """
|
hint = """
|
||||||
If other functions can return a `Result`, why shouldn't `main`?"""
|
If other functions can return a `Result`, why shouldn't `main`?"""
|
||||||
|
|
||||||
[[exercises]]
|
[[exercises]]
|
||||||
name = "errorsn"
|
name = "errors4"
|
||||||
path = "exercises/error_handling/errorsn.rs"
|
path = "exercises/error_handling/errors4.rs"
|
||||||
mode = "test"
|
mode = "test"
|
||||||
hint = """
|
hint = """
|
||||||
First hint: To figure out what type should go where the ??? is, take a look
|
`PositiveNonzeroInteger::new` is always creating a new instance and returning an `Ok` result.
|
||||||
at the test helper function `test_with_str`, since it returns whatever
|
It should be doing some checking, returning an `Err` result if those checks fail, and only
|
||||||
`read_and_validate` returns and `test_with_str` has its signature fully
|
returning an `Ok` result if those checks determine that everything is... okay :)"""
|
||||||
specified.
|
|
||||||
|
|
||||||
|
|
||||||
Next hint: There are three places in `read_and_validate` that we call a
|
|
||||||
function that returns a `Result` (that is, the functions might fail).
|
|
||||||
Apply the `?` operator on those calls so that we return immediately from
|
|
||||||
`read_and_validate` if those function calls fail.
|
|
||||||
|
|
||||||
|
[[exercises]]
|
||||||
|
name = "errors5"
|
||||||
|
path = "exercises/error_handling/errors5.rs"
|
||||||
|
mode = "compile"
|
||||||
|
hint = """
|
||||||
|
Hint: There are two different possible `Result` types produced within
|
||||||
|
`main()`, which are propagated using `?` operators. How do we declare a
|
||||||
|
return type from `main()` that allows both?
|
||||||
|
|
||||||
Another hint: under the hood, the `?` operator calls `From::from`
|
Another hint: under the hood, the `?` operator calls `From::from`
|
||||||
on the error value to convert it to a boxed trait object, a Box<dyn error::Error>,
|
on the error value to convert it to a boxed trait object, a
|
||||||
which is polymorphic-- that means that lots of different kinds of errors
|
`Box<dyn error::Error>`, which is polymorphic-- that means that lots of
|
||||||
can be returned from the same function because all errors act the same
|
different kinds of errors can be returned from the same function because
|
||||||
since they all implement the `error::Error` trait.
|
all errors act the same since they all implement the `error::Error` trait.
|
||||||
Check out this section of the book:
|
Check out this section of the book:
|
||||||
https://doc.rust-lang.org/book/ch09-02-recoverable-errors-with-result.html#a-shortcut-for-propagating-errors-the--operator
|
https://doc.rust-lang.org/book/ch09-02-recoverable-errors-with-result.html#a-shortcut-for-propagating-errors-the--operator
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
Another another hint: Note that because the `?` operator returns
|
Read more about boxing errors:
|
||||||
the *unwrapped* value in the `Ok` case, if we want to return a `Result` from
|
https://doc.rust-lang.org/stable/rust-by-example/error/multiple_error_types/boxing_errors.html
|
||||||
`read_and_validate` for *its* success case, we'll have to rewrap a value
|
|
||||||
that we got from the return value of a `?`ed call in an `Ok`-- this will
|
|
||||||
look like `Ok(something)`.
|
|
||||||
|
|
||||||
|
Read more about using the `?` operator with boxed errors:
|
||||||
|
https://doc.rust-lang.org/stable/rust-by-example/error/multiple_error_types/reenter_question_mark.html
|
||||||
|
"""
|
||||||
|
|
||||||
Another another another hint: `Result`s must be "used", that is, you'll
|
[[exercises]]
|
||||||
get a warning if you don't handle a `Result` that you get in your
|
name = "errors6"
|
||||||
function. Read more about that in the `std::result` module docs:
|
path = "exercises/error_handling/errors6.rs"
|
||||||
https://doc.rust-lang.org/std/result/#results-must-be-used"""
|
mode = "test"
|
||||||
|
hint = """
|
||||||
|
This exercise uses a completed version of `PositiveNonzeroInteger` from
|
||||||
|
errors4.
|
||||||
|
|
||||||
|
Below the line that TODO asks you to change, there is an example of using
|
||||||
|
the `map_err()` method on a `Result` to transform one type of error into
|
||||||
|
another. Try using something similar on the `Result` from `parse()`. You
|
||||||
|
might use the `?` operator to return early from the function, or you might
|
||||||
|
use a `match` expression, or maybe there's another way!
|
||||||
|
|
||||||
|
You can create another function inside `impl ParsePosNonzeroError` to use
|
||||||
|
with `map_err()`.
|
||||||
|
|
||||||
|
Read more about `map_err()` in the `std::result` documentation:
|
||||||
|
https://doc.rust-lang.org/std/result/enum.Result.html#method.map_err"""
|
||||||
|
|
||||||
# Generics
|
# Generics
|
||||||
|
|
||||||
|
@ -546,7 +580,7 @@ ReportCard struct generic, but also the correct property - you will need to chan
|
||||||
of the struct slightly too...you can do it!
|
of the struct slightly too...you can do it!
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# OPTIONS / RESULTS
|
# OPTIONS
|
||||||
|
|
||||||
[[exercises]]
|
[[exercises]]
|
||||||
name = "option1"
|
name = "option1"
|
||||||
|
@ -579,13 +613,14 @@ Also see Option::flatten
|
||||||
"""
|
"""
|
||||||
|
|
||||||
[[exercises]]
|
[[exercises]]
|
||||||
name = "result1"
|
name = "option3"
|
||||||
path = "exercises/error_handling/result1.rs"
|
path = "exercises/option/option3.rs"
|
||||||
mode = "test"
|
mode = "compile"
|
||||||
hint = """
|
hint = """
|
||||||
`PositiveNonzeroInteger::new` is always creating a new instance and returning an `Ok` result.
|
The compiler says a partial move happened in the `match`
|
||||||
It should be doing some checking, returning an `Err` result if those checks fail, and only
|
statement. How can this be avoided? The compiler shows the correction
|
||||||
returning an `Ok` result if those checks determine that everything is... okay :)"""
|
needed. After making the correction as suggested by the compiler, do
|
||||||
|
read: https://doc.rust-lang.org/std/keyword.ref.html"""
|
||||||
|
|
||||||
# TRAITS
|
# TRAITS
|
||||||
|
|
||||||
|
@ -679,7 +714,12 @@ to avoid creating a copy of `numbers`, you'll need to create `child_numbers`
|
||||||
inside the loop but still in the main thread.
|
inside the loop but still in the main thread.
|
||||||
|
|
||||||
`child_numbers` should be a clone of the Arc of the numbers instead of a
|
`child_numbers` should be a clone of the Arc of the numbers instead of a
|
||||||
thread-local copy of the numbers."""
|
thread-local copy of the numbers.
|
||||||
|
|
||||||
|
This is a simple exercise if you understand the underlying concepts, but if this
|
||||||
|
is too much of a struggle, consider reading through all of Chapter 16 in the book:
|
||||||
|
https://doc.rust-lang.org/stable/book/ch16-00-concurrency.html
|
||||||
|
"""
|
||||||
|
|
||||||
[[exercises]]
|
[[exercises]]
|
||||||
name = "iterators1"
|
name = "iterators1"
|
||||||
|
@ -694,7 +734,7 @@ Step 2 & step 2.1:
|
||||||
Very similar to the lines above and below. You've got this!
|
Very similar to the lines above and below. You've got this!
|
||||||
Step 3:
|
Step 3:
|
||||||
An iterator goes through all elements in a collection, but what if we've run out of
|
An iterator goes through all elements in a collection, but what if we've run out of
|
||||||
elements? What should we expect here? If you're stuck, take a look at
|
elements? What should we expect here? If you're stuck, take a look at
|
||||||
https://doc.rust-lang.org/std/iter/trait.Iterator.html for some ideas.
|
https://doc.rust-lang.org/std/iter/trait.Iterator.html for some ideas.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -704,32 +744,38 @@ path = "exercises/standard_library_types/iterators2.rs"
|
||||||
mode = "test"
|
mode = "test"
|
||||||
hint = """
|
hint = """
|
||||||
Step 1
|
Step 1
|
||||||
You need to call something on `first` before it can be collected
|
The variable `first` is a `char`. It needs to be capitalized and added to the
|
||||||
Currently its type is `char`. Have a look at the methods that are available on that type:
|
remaining characters in `c` in order to return the correct `String`.
|
||||||
|
The remaining characters in `c` can be viewed as a string slice using the
|
||||||
|
`as_str` method.
|
||||||
|
The documentation for `char` contains many useful methods.
|
||||||
https://doc.rust-lang.org/std/primitive.char.html
|
https://doc.rust-lang.org/std/primitive.char.html
|
||||||
|
|
||||||
|
|
||||||
Step 2
|
Step 2
|
||||||
First you'll need to turn the Vec into an iterator
|
Create an iterator from the slice. Transform the iterated values by applying
|
||||||
Then you'll need to apply your function unto each item in the vector
|
the `capitalize_first` function. Remember to collect the iterator.
|
||||||
P.s. Don't forget to collect() at the end!
|
|
||||||
|
|
||||||
|
|
||||||
Step 3.
|
Step 3.
|
||||||
This is very similar to the previous test. The only real change is that you will need to
|
This is surprising similar to the previous solution. Collect is very powerful
|
||||||
alter the type that collect is coerced into. For a bonus you could try doing this with a
|
and very general. Rust just needs to know the desired type."""
|
||||||
turbofish"""
|
|
||||||
|
|
||||||
[[exercises]]
|
[[exercises]]
|
||||||
name = "iterators3"
|
name = "iterators3"
|
||||||
path = "exercises/standard_library_types/iterators3.rs"
|
path = "exercises/standard_library_types/iterators3.rs"
|
||||||
mode = "test"
|
mode = "test"
|
||||||
hint = """
|
hint = """
|
||||||
Minor hint: In each of the two cases in the match in main, you can create x with either
|
The divide function needs to return the correct error when even division is not
|
||||||
a 'turbofish' or by hinting the type of x to the compiler. You may try both.
|
possible.
|
||||||
|
|
||||||
Major hint: Have a look at the Iter trait and at the explanation of its collect function.
|
The division_results variable needs to be collected into a collection type.
|
||||||
Especially the part about Result is interesting."""
|
|
||||||
|
The result_with_list function needs to return a single Result where the success
|
||||||
|
case is a vector of integers and the failure case is a DivisionError.
|
||||||
|
|
||||||
|
The list_of_results function needs to return a vector of results.
|
||||||
|
|
||||||
|
See https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.collect for how
|
||||||
|
the `FromIterator` trait is used in `collect()`."""
|
||||||
|
|
||||||
[[exercises]]
|
[[exercises]]
|
||||||
name = "iterators4"
|
name = "iterators4"
|
||||||
|
@ -741,6 +787,25 @@ a mutable variable. Or, you might write code utilizing recursion
|
||||||
and a match clause. In Rust you can take another functional
|
and a match clause. In Rust you can take another functional
|
||||||
approach, computing the factorial elegantly with ranges and iterators."""
|
approach, computing the factorial elegantly with ranges and iterators."""
|
||||||
|
|
||||||
|
[[exercises]]
|
||||||
|
name = "iterators5"
|
||||||
|
path = "exercises/standard_library_types/iterators5.rs"
|
||||||
|
mode = "test"
|
||||||
|
hint = """
|
||||||
|
The documentation for the std::iter::Iterator trait contains numerous methods
|
||||||
|
that would be helpful here.
|
||||||
|
|
||||||
|
Return 0 from count_collection_iterator to make the code compile in order to
|
||||||
|
test count_iterator.
|
||||||
|
|
||||||
|
The collection variable in count_collection_iterator is a slice of HashMaps. It
|
||||||
|
needs to be converted into an iterator in order to use the iterator methods.
|
||||||
|
|
||||||
|
The fold method can be useful in the count_collection_iterator function.
|
||||||
|
|
||||||
|
For a further challenge, consult the documentation for Iterator to find
|
||||||
|
a different method that could make your code more compact than using fold."""
|
||||||
|
|
||||||
# THREADS
|
# THREADS
|
||||||
|
|
||||||
[[exercises]]
|
[[exercises]]
|
||||||
|
@ -837,7 +902,15 @@ name = "clippy1"
|
||||||
path = "exercises/clippy/clippy1.rs"
|
path = "exercises/clippy/clippy1.rs"
|
||||||
mode = "clippy"
|
mode = "clippy"
|
||||||
hint = """
|
hint = """
|
||||||
Floating point calculations are usually imprecise, so asking if two values are exactly equal is asking for trouble"""
|
Not every floating point value can be represented exactly in binary values in
|
||||||
|
memory. Take a look at the description of
|
||||||
|
https://doc.rust-lang.org/stable/std/primitive.f32.html
|
||||||
|
When using the binary compare operators with floating points you won't compare
|
||||||
|
the floating point values but the binary representation in memory. This is
|
||||||
|
usually not what you would like to do.
|
||||||
|
See the suggestions of the clippy warning in compile output and use the
|
||||||
|
machine epsilon value...
|
||||||
|
https://doc.rust-lang.org/stable/std/primitive.f32.html#associatedconstant.EPSILON"""
|
||||||
|
|
||||||
[[exercises]]
|
[[exercises]]
|
||||||
name = "clippy2"
|
name = "clippy2"
|
||||||
|
@ -869,7 +942,19 @@ path = "exercises/conversions/try_from_into.rs"
|
||||||
mode = "test"
|
mode = "test"
|
||||||
hint = """
|
hint = """
|
||||||
Follow the steps provided right before the `TryFrom` implementation.
|
Follow the steps provided right before the `TryFrom` implementation.
|
||||||
You can also use the example at https://doc.rust-lang.org/std/convert/trait.TryFrom.html"""
|
You can also use the example at https://doc.rust-lang.org/std/convert/trait.TryFrom.html
|
||||||
|
|
||||||
|
You might want to look back at the exercise errors5 (or its hints) to remind
|
||||||
|
yourself about how `Box<dyn Error>` works.
|
||||||
|
|
||||||
|
If you're trying to return a string as an error, note that neither `str`
|
||||||
|
nor `String` implements `error::Error`. However, there is an implementation
|
||||||
|
of `From<&str>` for `Box<dyn Error>`. This means you can use `.into()` or
|
||||||
|
the `?` operator to convert your string into the correct error type.
|
||||||
|
|
||||||
|
If you're having trouble with using the `?` operator to convert an error string,
|
||||||
|
recall that `?` works to convert `Err(something)` into the appropriate error
|
||||||
|
type for returning from the function."""
|
||||||
|
|
||||||
[[exercises]]
|
[[exercises]]
|
||||||
name = "as_ref_mut"
|
name = "as_ref_mut"
|
||||||
|
@ -884,5 +969,8 @@ path = "exercises/conversions/from_str.rs"
|
||||||
mode = "test"
|
mode = "test"
|
||||||
hint = """
|
hint = """
|
||||||
The implementation of FromStr should return an Ok with a Person object,
|
The implementation of FromStr should return an Ok with a Person object,
|
||||||
or an Err with a string if the string is not valid.
|
or an Err with an error if the string is not valid.
|
||||||
This is almost like the `try_from_into` exercise."""
|
This is almost like the `try_from_into` exercise.
|
||||||
|
|
||||||
|
If you're having trouble with returning the correct error type, see the
|
||||||
|
hints for try_from_into."""
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
use std::env;
|
||||||
use std::fmt::{self, Display, Formatter};
|
use std::fmt::{self, Display, Formatter};
|
||||||
use std::fs::{self, remove_file, File};
|
use std::fs::{self, remove_file, File};
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
|
@ -23,7 +24,7 @@ fn temp_file() -> String {
|
||||||
}
|
}
|
||||||
|
|
||||||
// The mode of the exercise.
|
// The mode of the exercise.
|
||||||
#[derive(Deserialize, Copy, Clone)]
|
#[derive(Deserialize, Copy, Clone, Debug)]
|
||||||
#[serde(rename_all = "lowercase")]
|
#[serde(rename_all = "lowercase")]
|
||||||
pub enum Mode {
|
pub enum Mode {
|
||||||
// Indicates that the exercise should be compiled as a binary
|
// Indicates that the exercise should be compiled as a binary
|
||||||
|
@ -41,7 +42,7 @@ pub struct ExerciseList {
|
||||||
|
|
||||||
// A representation of a rustlings exercise.
|
// A representation of a rustlings exercise.
|
||||||
// This is deserialized from the accompanying info.toml file
|
// This is deserialized from the accompanying info.toml file
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize, Debug)]
|
||||||
pub struct Exercise {
|
pub struct Exercise {
|
||||||
// Name of the exercise
|
// Name of the exercise
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
@ -126,8 +127,12 @@ name = "{}"
|
||||||
path = "{}.rs""#,
|
path = "{}.rs""#,
|
||||||
self.name, self.name, self.name
|
self.name, self.name, self.name
|
||||||
);
|
);
|
||||||
fs::write(CLIPPY_CARGO_TOML_PATH, cargo_toml)
|
let cargo_toml_error_msg = if env::var("NO_EMOJI").is_ok() {
|
||||||
.expect("Failed to write 📎 Clippy 📎 Cargo.toml file.");
|
"Failed to write Clippy Cargo.toml file."
|
||||||
|
} else {
|
||||||
|
"Failed to write 📎 Clippy 📎 Cargo.toml file."
|
||||||
|
};
|
||||||
|
fs::write(CLIPPY_CARGO_TOML_PATH, cargo_toml).expect(cargo_toml_error_msg);
|
||||||
// To support the ability to run the clipy exercises, build
|
// To support the ability to run the clipy exercises, build
|
||||||
// an executable, in addition to running clippy. With a
|
// an executable, in addition to running clippy. With a
|
||||||
// compilation failure, this would silently fail. But we expect
|
// compilation failure, this would silently fail. But we expect
|
||||||
|
@ -235,7 +240,7 @@ path = "{}.rs""#,
|
||||||
|
|
||||||
// Check that the exercise looks to be solved using self.state()
|
// Check that the exercise looks to be solved using self.state()
|
||||||
// This is not the best way to check since
|
// This is not the best way to check since
|
||||||
// the user can just remove the "I AM NOT DONE" string fromm the file
|
// the user can just remove the "I AM NOT DONE" string from the file
|
||||||
// without actually having solved anything.
|
// without actually having solved anything.
|
||||||
// The only other way to truly check this would to compile and run
|
// The only other way to truly check this would to compile and run
|
||||||
// the exercise; which would be both costly and counterintuitive
|
// the exercise; which would be both costly and counterintuitive
|
||||||
|
|
431
src/main.rs
431
src/main.rs
|
@ -1,7 +1,7 @@
|
||||||
use crate::exercise::{Exercise, ExerciseList};
|
use crate::exercise::{Exercise, ExerciseList};
|
||||||
use crate::run::run;
|
use crate::run::run;
|
||||||
use crate::verify::verify;
|
use crate::verify::verify;
|
||||||
use clap::{crate_version, App, Arg, SubCommand};
|
use argh::FromArgs;
|
||||||
use console::Emoji;
|
use console::Emoji;
|
||||||
use notify::DebouncedEvent;
|
use notify::DebouncedEvent;
|
||||||
use notify::{RecommendedWatcher, RecursiveMode, Watcher};
|
use notify::{RecommendedWatcher, RecursiveMode, Watcher};
|
||||||
|
@ -22,85 +22,91 @@ mod exercise;
|
||||||
mod run;
|
mod run;
|
||||||
mod verify;
|
mod verify;
|
||||||
|
|
||||||
fn main() {
|
// In sync with crate version
|
||||||
let matches = App::new("rustlings")
|
const VERSION: &str = "4.4.0";
|
||||||
.version(crate_version!())
|
|
||||||
.author("Marisa, Carol Nichols")
|
|
||||||
.about("Rustlings is a collection of small exercises to get you used to writing and reading Rust code")
|
|
||||||
.arg(
|
|
||||||
Arg::with_name("nocapture")
|
|
||||||
.long("nocapture")
|
|
||||||
.help("Show outputs from the test exercises")
|
|
||||||
)
|
|
||||||
.subcommand(
|
|
||||||
SubCommand::with_name("verify")
|
|
||||||
.alias("v")
|
|
||||||
.about("Verifies all exercises according to the recommended order")
|
|
||||||
)
|
|
||||||
.subcommand(
|
|
||||||
SubCommand::with_name("watch")
|
|
||||||
.alias("w")
|
|
||||||
.about("Reruns `verify` when files were edited")
|
|
||||||
)
|
|
||||||
.subcommand(
|
|
||||||
SubCommand::with_name("run")
|
|
||||||
.alias("r")
|
|
||||||
.about("Runs/Tests a single exercise")
|
|
||||||
.arg(Arg::with_name("name").required(true).index(1)),
|
|
||||||
)
|
|
||||||
.subcommand(
|
|
||||||
SubCommand::with_name("hint")
|
|
||||||
.alias("h")
|
|
||||||
.about("Returns a hint for the current exercise")
|
|
||||||
.arg(Arg::with_name("name").required(true).index(1)),
|
|
||||||
)
|
|
||||||
.subcommand(
|
|
||||||
SubCommand::with_name("list")
|
|
||||||
.alias("l")
|
|
||||||
.about("Lists the exercises available in rustlings")
|
|
||||||
.arg(
|
|
||||||
Arg::with_name("paths")
|
|
||||||
.long("paths")
|
|
||||||
.short("p")
|
|
||||||
.conflicts_with("names")
|
|
||||||
.help("Show only the paths of the exercises")
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::with_name("names")
|
|
||||||
.long("names")
|
|
||||||
.short("n")
|
|
||||||
.conflicts_with("paths")
|
|
||||||
.help("Show only the names of the exercises")
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::with_name("filter")
|
|
||||||
.long("filter")
|
|
||||||
.short("f")
|
|
||||||
.takes_value(true)
|
|
||||||
.empty_values(false)
|
|
||||||
.help(
|
|
||||||
"Provide a string to match the exercise names.\
|
|
||||||
\nComma separated patterns are acceptable."
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::with_name("unsolved")
|
|
||||||
.long("unsolved")
|
|
||||||
.short("u")
|
|
||||||
.conflicts_with("solved")
|
|
||||||
.help("Display only exercises not yet solved")
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::with_name("solved")
|
|
||||||
.long("solved")
|
|
||||||
.short("s")
|
|
||||||
.conflicts_with("unsolved")
|
|
||||||
.help("Display only exercises that have been solved")
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.get_matches();
|
|
||||||
|
|
||||||
if matches.subcommand_name().is_none() {
|
#[derive(FromArgs, PartialEq, Debug)]
|
||||||
|
/// Rustlings is a collection of small exercises to get you used to writing and reading Rust code
|
||||||
|
struct Args {
|
||||||
|
/// show outputs from the test exercises
|
||||||
|
#[argh(switch)]
|
||||||
|
nocapture: bool,
|
||||||
|
/// show the executable version
|
||||||
|
#[argh(switch, short = 'v')]
|
||||||
|
version: bool,
|
||||||
|
#[argh(subcommand)]
|
||||||
|
nested: Option<Subcommands>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(FromArgs, PartialEq, Debug)]
|
||||||
|
#[argh(subcommand)]
|
||||||
|
enum Subcommands {
|
||||||
|
Verify(VerifyArgs),
|
||||||
|
Watch(WatchArgs),
|
||||||
|
Run(RunArgs),
|
||||||
|
Hint(HintArgs),
|
||||||
|
List(ListArgs),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(FromArgs, PartialEq, Debug)]
|
||||||
|
#[argh(subcommand, name = "verify")]
|
||||||
|
/// Verifies all exercises according to the recommended order
|
||||||
|
struct VerifyArgs {}
|
||||||
|
|
||||||
|
#[derive(FromArgs, PartialEq, Debug)]
|
||||||
|
#[argh(subcommand, name = "watch")]
|
||||||
|
/// Reruns `verify` when files were edited
|
||||||
|
struct WatchArgs {}
|
||||||
|
|
||||||
|
#[derive(FromArgs, PartialEq, Debug)]
|
||||||
|
#[argh(subcommand, name = "run")]
|
||||||
|
/// Runs/Tests a single exercise
|
||||||
|
struct RunArgs {
|
||||||
|
#[argh(positional)]
|
||||||
|
/// the name of the exercise
|
||||||
|
name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(FromArgs, PartialEq, Debug)]
|
||||||
|
#[argh(subcommand, name = "hint")]
|
||||||
|
/// Returns a hint for the given exercise
|
||||||
|
struct HintArgs {
|
||||||
|
#[argh(positional)]
|
||||||
|
/// the name of the exercise
|
||||||
|
name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(FromArgs, PartialEq, Debug)]
|
||||||
|
#[argh(subcommand, name = "list")]
|
||||||
|
/// Lists the exercises available in Rustlings
|
||||||
|
struct ListArgs {
|
||||||
|
#[argh(switch, short = 'p')]
|
||||||
|
/// show only the paths of the exercises
|
||||||
|
paths: bool,
|
||||||
|
#[argh(switch, short = 'n')]
|
||||||
|
/// show only the names of the exercises
|
||||||
|
names: bool,
|
||||||
|
#[argh(option, short = 'f')]
|
||||||
|
/// provide a string to match exercise names
|
||||||
|
/// comma separated patterns are acceptable
|
||||||
|
filter: Option<String>,
|
||||||
|
#[argh(switch, short = 'u')]
|
||||||
|
/// display only exercises not yet solved
|
||||||
|
unsolved: bool,
|
||||||
|
#[argh(switch, short = 's')]
|
||||||
|
/// display only exercises that have been solved
|
||||||
|
solved: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let args: Args = argh::from_env();
|
||||||
|
|
||||||
|
if args.version {
|
||||||
|
println!("v{}", VERSION);
|
||||||
|
std::process::exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if args.nested.is_none() {
|
||||||
println!();
|
println!();
|
||||||
println!(r#" welcome to... "#);
|
println!(r#" welcome to... "#);
|
||||||
println!(r#" _ _ _ "#);
|
println!(r#" _ _ _ "#);
|
||||||
|
@ -130,137 +136,135 @@ fn main() {
|
||||||
|
|
||||||
let toml_str = &fs::read_to_string("info.toml").unwrap();
|
let toml_str = &fs::read_to_string("info.toml").unwrap();
|
||||||
let exercises = toml::from_str::<ExerciseList>(toml_str).unwrap().exercises;
|
let exercises = toml::from_str::<ExerciseList>(toml_str).unwrap().exercises;
|
||||||
let verbose = matches.is_present("nocapture");
|
let verbose = args.nocapture;
|
||||||
|
|
||||||
// Handle the list command
|
let command = args.nested.unwrap_or_else(|| {
|
||||||
if let Some(list_m) = matches.subcommand_matches("list") {
|
|
||||||
if ["paths", "names"].iter().all(|k| !list_m.is_present(k)) {
|
|
||||||
println!("{:<17}\t{:<46}\t{:<7}", "Name", "Path", "Status");
|
|
||||||
}
|
|
||||||
let filters = list_m.value_of("filter").unwrap_or_default().to_lowercase();
|
|
||||||
exercises.iter().for_each(|e| {
|
|
||||||
let fname = format!("{}", e.path.display());
|
|
||||||
let filter_cond = filters
|
|
||||||
.split(',')
|
|
||||||
.filter(|f| f.trim().len() > 0)
|
|
||||||
.any(|f| e.name.contains(&f) || fname.contains(&f));
|
|
||||||
let status = if e.looks_done() { "Done" } else { "Pending" };
|
|
||||||
let solve_cond = {
|
|
||||||
(e.looks_done() && list_m.is_present("solved"))
|
|
||||||
|| (!e.looks_done() && list_m.is_present("unsolved"))
|
|
||||||
|| (!list_m.is_present("solved") && !list_m.is_present("unsolved"))
|
|
||||||
};
|
|
||||||
if solve_cond && (filter_cond || !list_m.is_present("filter")) {
|
|
||||||
let line = if list_m.is_present("paths") {
|
|
||||||
format!("{}\n", fname)
|
|
||||||
} else if list_m.is_present("names") {
|
|
||||||
format!("{}\n", e.name)
|
|
||||||
} else {
|
|
||||||
format!("{:<17}\t{:<46}\t{:<7}\n", e.name, fname, status)
|
|
||||||
};
|
|
||||||
// Somehow using println! leads to the binary panicking
|
|
||||||
// when its output is piped.
|
|
||||||
// So, we're handling a Broken Pipe error and exiting with 0 anyway
|
|
||||||
let stdout = std::io::stdout();
|
|
||||||
{
|
|
||||||
let mut handle = stdout.lock();
|
|
||||||
handle.write_all(line.as_bytes()).unwrap_or_else(|e| {
|
|
||||||
match e.kind() {
|
|
||||||
std::io::ErrorKind::BrokenPipe => std::process::exit(0),
|
|
||||||
_ => std::process::exit(1),
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
std::process::exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle the run command
|
|
||||||
if let Some(ref matches) = matches.subcommand_matches("run") {
|
|
||||||
let name = matches.value_of("name").unwrap();
|
|
||||||
|
|
||||||
let matching_exercise = |e: &&Exercise| name == e.name;
|
|
||||||
|
|
||||||
let exercise = exercises.iter().find(matching_exercise).unwrap_or_else(|| {
|
|
||||||
println!("No exercise found for your given name!");
|
|
||||||
std::process::exit(1)
|
|
||||||
});
|
|
||||||
|
|
||||||
run(&exercise, verbose).unwrap_or_else(|_| std::process::exit(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(ref matches) = matches.subcommand_matches("hint") {
|
|
||||||
let name = matches.value_of("name").unwrap();
|
|
||||||
|
|
||||||
let exercise = exercises
|
|
||||||
.iter()
|
|
||||||
.find(|e| name == e.name)
|
|
||||||
.unwrap_or_else(|| {
|
|
||||||
println!("No exercise found for your given name!");
|
|
||||||
std::process::exit(1)
|
|
||||||
});
|
|
||||||
|
|
||||||
println!("{}", exercise.hint);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle the verify command
|
|
||||||
if matches.subcommand_matches("verify").is_some() {
|
|
||||||
verify(&exercises, verbose).unwrap_or_else(|_| std::process::exit(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle the watch command
|
|
||||||
if matches.subcommand_matches("watch").is_some() {
|
|
||||||
if let Err(e) = watch(&exercises, verbose) {
|
|
||||||
println!(
|
|
||||||
"Error: Could not watch your progess. 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);
|
|
||||||
}
|
|
||||||
println!(
|
|
||||||
"{emoji} All exercises completed! {emoji}",
|
|
||||||
emoji = Emoji("🎉", "★")
|
|
||||||
);
|
|
||||||
println!();
|
|
||||||
println!("+----------------------------------------------------+");
|
|
||||||
println!("| You made it to the Fe-nish line! |");
|
|
||||||
println!("+-------------------------- ------------------------+");
|
|
||||||
println!(" \\/ ");
|
|
||||||
println!(" ▒▒ ▒▒▒▒▒▒▒▒ ▒▒▒▒▒▒▒▒ ▒▒ ");
|
|
||||||
println!(" ▒▒▒▒ ▒▒ ▒▒ ▒▒ ▒▒ ▒▒ ▒▒ ▒▒▒▒ ");
|
|
||||||
println!(" ▒▒▒▒ ▒▒ ▒▒ ▒▒ ▒▒ ▒▒ ▒▒▒▒ ");
|
|
||||||
println!(" ░░▒▒▒▒░░▒▒ ▒▒ ▒▒ ▒▒ ▒▒░░▒▒▒▒ ");
|
|
||||||
println!(" ▓▓▓▓▓▓▓▓ ▓▓ ▓▓██ ▓▓ ▓▓██ ▓▓ ▓▓▓▓▓▓▓▓ ");
|
|
||||||
println!(" ▒▒▒▒ ▒▒ ████ ▒▒ ████ ▒▒░░ ▒▒▒▒ ");
|
|
||||||
println!(" ▒▒ ▒▒▒▒▒▒ ▒▒▒▒▒▒ ▒▒▒▒▒▒ ▒▒ ");
|
|
||||||
println!(" ▒▒▒▒▒▒▒▒▒▒▓▓▓▓▓▓▒▒▒▒▒▒▒▒▓▓▒▒▓▓▒▒▒▒▒▒▒▒ ");
|
|
||||||
println!(" ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ ");
|
|
||||||
println!(" ▒▒▒▒▒▒▒▒▒▒██▒▒▒▒▒▒██▒▒▒▒▒▒▒▒▒▒ ");
|
|
||||||
println!(" ▒▒ ▒▒▒▒▒▒▒▒▒▒██████▒▒▒▒▒▒▒▒▒▒ ▒▒ ");
|
|
||||||
println!(" ▒▒ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ ▒▒ ");
|
|
||||||
println!(" ▒▒ ▒▒ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ ▒▒ ▒▒ ");
|
|
||||||
println!(" ▒▒ ▒▒ ▒▒ ▒▒ ▒▒ ▒▒ ");
|
|
||||||
println!(" ▒▒ ▒▒ ▒▒ ▒▒ ");
|
|
||||||
println!();
|
|
||||||
println!("We hope you enjoyed learning about the various aspects of Rust!");
|
|
||||||
println!("If you noticed any issues, please don't hesitate to report them to our repo.");
|
|
||||||
println!("You can also contribute your own exercises to help the greater community!");
|
|
||||||
println!();
|
|
||||||
println!("Before reporting an issue or contributing, please read our guidelines:");
|
|
||||||
println!("https://github.com/rust-lang/rustlings/blob/main/CONTRIBUTING.md");
|
|
||||||
}
|
|
||||||
|
|
||||||
if matches.subcommand_name().is_none() {
|
|
||||||
let text = fs::read_to_string("default_out.txt").unwrap();
|
let text = fs::read_to_string("default_out.txt").unwrap();
|
||||||
println!("{}", text);
|
println!("{}", text);
|
||||||
|
std::process::exit(0);
|
||||||
|
});
|
||||||
|
match command {
|
||||||
|
Subcommands::List(subargs) => {
|
||||||
|
if !subargs.paths && !subargs.names {
|
||||||
|
println!("{:<17}\t{:<46}\t{:<7}", "Name", "Path", "Status");
|
||||||
|
}
|
||||||
|
let mut exercises_done: u16 = 0;
|
||||||
|
let filters = subargs.filter.clone().unwrap_or_default().to_lowercase();
|
||||||
|
exercises.iter().for_each(|e| {
|
||||||
|
let fname = format!("{}", e.path.display());
|
||||||
|
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() {
|
||||||
|
exercises_done += 1;
|
||||||
|
"Done"
|
||||||
|
} else {
|
||||||
|
"Pending"
|
||||||
|
};
|
||||||
|
let solve_cond = {
|
||||||
|
(e.looks_done() && subargs.solved)
|
||||||
|
|| (!e.looks_done() && subargs.unsolved)
|
||||||
|
|| (!subargs.solved && !subargs.unsolved)
|
||||||
|
};
|
||||||
|
if solve_cond && (filter_cond || subargs.filter.is_none()) {
|
||||||
|
let line = if subargs.paths {
|
||||||
|
format!("{}\n", fname)
|
||||||
|
} else if subargs.names {
|
||||||
|
format!("{}\n", e.name)
|
||||||
|
} else {
|
||||||
|
format!("{:<17}\t{:<46}\t{:<7}\n", e.name, fname, status)
|
||||||
|
};
|
||||||
|
// Somehow using println! leads to the binary panicking
|
||||||
|
// when its output is piped.
|
||||||
|
// So, we're handling a Broken Pipe error and exiting with 0 anyway
|
||||||
|
let stdout = std::io::stdout();
|
||||||
|
{
|
||||||
|
let mut handle = stdout.lock();
|
||||||
|
handle.write_all(line.as_bytes()).unwrap_or_else(|e| {
|
||||||
|
match e.kind() {
|
||||||
|
std::io::ErrorKind::BrokenPipe => std::process::exit(0),
|
||||||
|
_ => std::process::exit(1),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let percentage_progress = exercises_done as f32 / exercises.len() as f32 * 100.0;
|
||||||
|
println!(
|
||||||
|
"Progress: You completed {} / {} exercises ({:.2} %).",
|
||||||
|
exercises_done,
|
||||||
|
exercises.len(),
|
||||||
|
percentage_progress
|
||||||
|
);
|
||||||
|
std::process::exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Subcommands::Run(subargs) => {
|
||||||
|
let exercise = find_exercise(&subargs.name, &exercises);
|
||||||
|
|
||||||
|
run(&exercise, verbose).unwrap_or_else(|_| std::process::exit(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
Subcommands::Hint(subargs) => {
|
||||||
|
let exercise = find_exercise(&subargs.name, &exercises);
|
||||||
|
|
||||||
|
println!("{}", exercise.hint);
|
||||||
|
}
|
||||||
|
|
||||||
|
Subcommands::Verify(_subargs) => {
|
||||||
|
verify(&exercises, verbose).unwrap_or_else(|_| std::process::exit(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
Subcommands::Watch(_subargs) => {
|
||||||
|
if let Err(e) = watch(&exercises, verbose) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
println!(
|
||||||
|
"{emoji} All exercises completed! {emoji}",
|
||||||
|
emoji = Emoji("🎉", "★")
|
||||||
|
);
|
||||||
|
println!();
|
||||||
|
println!("+----------------------------------------------------+");
|
||||||
|
println!("| You made it to the Fe-nish line! |");
|
||||||
|
println!("+-------------------------- ------------------------+");
|
||||||
|
println!(" \\/ ");
|
||||||
|
println!(" ▒▒ ▒▒▒▒▒▒▒▒ ▒▒▒▒▒▒▒▒ ▒▒ ");
|
||||||
|
println!(" ▒▒▒▒ ▒▒ ▒▒ ▒▒ ▒▒ ▒▒ ▒▒ ▒▒▒▒ ");
|
||||||
|
println!(" ▒▒▒▒ ▒▒ ▒▒ ▒▒ ▒▒ ▒▒ ▒▒▒▒ ");
|
||||||
|
println!(" ░░▒▒▒▒░░▒▒ ▒▒ ▒▒ ▒▒ ▒▒░░▒▒▒▒ ");
|
||||||
|
println!(" ▓▓▓▓▓▓▓▓ ▓▓ ▓▓██ ▓▓ ▓▓██ ▓▓ ▓▓▓▓▓▓▓▓ ");
|
||||||
|
println!(" ▒▒▒▒ ▒▒ ████ ▒▒ ████ ▒▒░░ ▒▒▒▒ ");
|
||||||
|
println!(" ▒▒ ▒▒▒▒▒▒ ▒▒▒▒▒▒ ▒▒▒▒▒▒ ▒▒ ");
|
||||||
|
println!(" ▒▒▒▒▒▒▒▒▒▒▓▓▓▓▓▓▒▒▒▒▒▒▒▒▓▓▒▒▓▓▒▒▒▒▒▒▒▒ ");
|
||||||
|
println!(" ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ ");
|
||||||
|
println!(" ▒▒▒▒▒▒▒▒▒▒██▒▒▒▒▒▒██▒▒▒▒▒▒▒▒▒▒ ");
|
||||||
|
println!(" ▒▒ ▒▒▒▒▒▒▒▒▒▒██████▒▒▒▒▒▒▒▒▒▒ ▒▒ ");
|
||||||
|
println!(" ▒▒ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ ▒▒ ");
|
||||||
|
println!(" ▒▒ ▒▒ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ ▒▒ ▒▒ ");
|
||||||
|
println!(" ▒▒ ▒▒ ▒▒ ▒▒ ▒▒ ▒▒ ");
|
||||||
|
println!(" ▒▒ ▒▒ ▒▒ ▒▒ ");
|
||||||
|
println!();
|
||||||
|
println!("We hope you enjoyed learning about the various aspects of Rust!");
|
||||||
|
println!(
|
||||||
|
"If you noticed any issues, please don't hesitate to report them to our repo."
|
||||||
|
);
|
||||||
|
println!("You can also contribute your own exercises to help the greater community!");
|
||||||
|
println!();
|
||||||
|
println!("Before reporting an issue or contributing, please read our guidelines:");
|
||||||
|
println!("https://github.com/rust-lang/rustlings/blob/main/CONTRIBUTING.md");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn spawn_watch_shell(failed_exercise_hint: &Arc<Mutex<Option<String>>>) {
|
fn spawn_watch_shell(failed_exercise_hint: &Arc<Mutex<Option<String>>>) {
|
||||||
let failed_exercise_hint = Arc::clone(failed_exercise_hint);
|
let failed_exercise_hint = Arc::clone(failed_exercise_hint);
|
||||||
println!("Type 'hint' to get help or 'clear' to clear the screen");
|
println!("Type 'hint' or open the corresponding README.md file to get help or type 'clear' to clear the screen.");
|
||||||
thread::spawn(move || loop {
|
thread::spawn(move || loop {
|
||||||
let mut input = String::new();
|
let mut input = String::new();
|
||||||
match io::stdin().read_line(&mut input) {
|
match io::stdin().read_line(&mut input) {
|
||||||
|
@ -281,6 +285,27 @@ fn spawn_watch_shell(failed_exercise_hint: &Arc<Mutex<Option<String>>>) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn find_exercise<'a>(name: &str, exercises: &'a [Exercise]) -> &'a Exercise {
|
||||||
|
if name.eq("next") {
|
||||||
|
exercises
|
||||||
|
.iter()
|
||||||
|
.find(|e| !e.looks_done())
|
||||||
|
.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 {
|
||||||
|
exercises
|
||||||
|
.iter()
|
||||||
|
.find(|e| e.name == name)
|
||||||
|
.unwrap_or_else(|| {
|
||||||
|
println!("No exercise found for '{}'!", name);
|
||||||
|
std::process::exit(1)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn watch(exercises: &[Exercise], verbose: bool) -> notify::Result<()> {
|
fn watch(exercises: &[Exercise], verbose: bool) -> notify::Result<()> {
|
||||||
/* Clears the terminal with an ANSI escape code.
|
/* Clears the terminal with an ANSI escape code.
|
||||||
Works in UNIX and newer Windows terminals. */
|
Works in UNIX and newer Windows terminals. */
|
||||||
|
@ -314,7 +339,7 @@ fn watch(exercises: &[Exercise], verbose: bool) -> notify::Result<()> {
|
||||||
.chain(
|
.chain(
|
||||||
exercises
|
exercises
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|e| !e.looks_done() && !filepath.ends_with(&e.path))
|
.filter(|e| !e.looks_done() && !filepath.ends_with(&e.path)),
|
||||||
);
|
);
|
||||||
clear_screen();
|
clear_screen();
|
||||||
match verify(pending_exercises, verbose) {
|
match verify(pending_exercises, verbose) {
|
||||||
|
|
30
src/ui.rs
30
src/ui.rs
|
@ -1,23 +1,33 @@
|
||||||
macro_rules! warn {
|
macro_rules! warn {
|
||||||
($fmt:literal, $ex:expr) => {{
|
($fmt:literal, $ex:expr) => {{
|
||||||
use console::{style, Emoji};
|
use console::{style, Emoji};
|
||||||
|
use std::env;
|
||||||
let formatstr = format!($fmt, $ex);
|
let formatstr = format!($fmt, $ex);
|
||||||
println!(
|
if env::var("NO_EMOJI").is_ok() {
|
||||||
"{} {}",
|
println!("{} {}", style("!").red(), style(formatstr).red());
|
||||||
style(Emoji("⚠️ ", "!")).red(),
|
} else {
|
||||||
style(formatstr).red()
|
println!(
|
||||||
);
|
"{} {}",
|
||||||
|
style(Emoji("⚠️ ", "!")).red(),
|
||||||
|
style(formatstr).red()
|
||||||
|
);
|
||||||
|
}
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! success {
|
macro_rules! success {
|
||||||
($fmt:literal, $ex:expr) => {{
|
($fmt:literal, $ex:expr) => {{
|
||||||
use console::{style, Emoji};
|
use console::{style, Emoji};
|
||||||
|
use std::env;
|
||||||
let formatstr = format!($fmt, $ex);
|
let formatstr = format!($fmt, $ex);
|
||||||
println!(
|
if env::var("NO_EMOJI").is_ok() {
|
||||||
"{} {}",
|
println!("{} {}", style("✓").green(), style(formatstr).green());
|
||||||
style(Emoji("✅", "✓")).green(),
|
} else {
|
||||||
style(formatstr).green()
|
println!(
|
||||||
);
|
"{} {}",
|
||||||
|
style(Emoji("✅", "✓")).green(),
|
||||||
|
style(formatstr).green()
|
||||||
|
);
|
||||||
|
}
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::exercise::{CompiledExercise, Exercise, Mode, State};
|
use crate::exercise::{CompiledExercise, Exercise, Mode, State};
|
||||||
use console::style;
|
use console::style;
|
||||||
use indicatif::ProgressBar;
|
use indicatif::ProgressBar;
|
||||||
|
use std::env;
|
||||||
|
|
||||||
// Verify that the provided container of Exercise objects
|
// Verify that the provided container of Exercise objects
|
||||||
// can be compiled and run without any failures.
|
// can be compiled and run without any failures.
|
||||||
|
@ -137,14 +138,26 @@ fn prompt_for_completion(exercise: &Exercise, prompt_output: Option<String>) ->
|
||||||
State::Pending(context) => context,
|
State::Pending(context) => context,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let no_emoji = env::var("NO_EMOJI").is_ok();
|
||||||
|
|
||||||
|
let clippy_success_msg = if no_emoji {
|
||||||
|
"The code is compiling, and Clippy is happy!"
|
||||||
|
} else {
|
||||||
|
"The code is compiling, and 📎 Clippy 📎 is happy!"
|
||||||
|
};
|
||||||
|
|
||||||
let success_msg = match exercise.mode {
|
let success_msg = match exercise.mode {
|
||||||
Mode::Compile => "The code is compiling!",
|
Mode::Compile => "The code is compiling!",
|
||||||
Mode::Test => "The code is compiling, and the tests pass!",
|
Mode::Test => "The code is compiling, and the tests pass!",
|
||||||
Mode::Clippy => "The code is compiling, and 📎 Clippy 📎 is happy!",
|
Mode::Clippy => clippy_success_msg,
|
||||||
};
|
};
|
||||||
|
|
||||||
println!();
|
println!();
|
||||||
println!("🎉 🎉 {} 🎉 🎉", success_msg);
|
if no_emoji {
|
||||||
|
println!("~*~ {} ~*~", success_msg)
|
||||||
|
} else {
|
||||||
|
println!("🎉 🎉 {} 🎉 🎉", success_msg)
|
||||||
|
}
|
||||||
println!();
|
println!();
|
||||||
|
|
||||||
if let Some(output) = prompt_output {
|
if let Some(output) = prompt_output {
|
||||||
|
|
|
@ -24,7 +24,7 @@ fn fails_when_in_wrong_dir() {
|
||||||
fn verify_all_success() {
|
fn verify_all_success() {
|
||||||
Command::cargo_bin("rustlings")
|
Command::cargo_bin("rustlings")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.arg("v")
|
.arg("verify")
|
||||||
.current_dir("tests/fixture/success")
|
.current_dir("tests/fixture/success")
|
||||||
.assert()
|
.assert()
|
||||||
.success();
|
.success();
|
||||||
|
@ -34,7 +34,7 @@ fn verify_all_success() {
|
||||||
fn verify_fails_if_some_fails() {
|
fn verify_fails_if_some_fails() {
|
||||||
Command::cargo_bin("rustlings")
|
Command::cargo_bin("rustlings")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.arg("v")
|
.arg("verify")
|
||||||
.current_dir("tests/fixture/failure")
|
.current_dir("tests/fixture/failure")
|
||||||
.assert()
|
.assert()
|
||||||
.code(1);
|
.code(1);
|
||||||
|
@ -44,7 +44,7 @@ fn verify_fails_if_some_fails() {
|
||||||
fn run_single_compile_success() {
|
fn run_single_compile_success() {
|
||||||
Command::cargo_bin("rustlings")
|
Command::cargo_bin("rustlings")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.args(&["r", "compSuccess"])
|
.args(&["run", "compSuccess"])
|
||||||
.current_dir("tests/fixture/success/")
|
.current_dir("tests/fixture/success/")
|
||||||
.assert()
|
.assert()
|
||||||
.success();
|
.success();
|
||||||
|
@ -54,7 +54,7 @@ fn run_single_compile_success() {
|
||||||
fn run_single_compile_failure() {
|
fn run_single_compile_failure() {
|
||||||
Command::cargo_bin("rustlings")
|
Command::cargo_bin("rustlings")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.args(&["r", "compFailure"])
|
.args(&["run", "compFailure"])
|
||||||
.current_dir("tests/fixture/failure/")
|
.current_dir("tests/fixture/failure/")
|
||||||
.assert()
|
.assert()
|
||||||
.code(1);
|
.code(1);
|
||||||
|
@ -64,7 +64,7 @@ fn run_single_compile_failure() {
|
||||||
fn run_single_test_success() {
|
fn run_single_test_success() {
|
||||||
Command::cargo_bin("rustlings")
|
Command::cargo_bin("rustlings")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.args(&["r", "testSuccess"])
|
.args(&["run", "testSuccess"])
|
||||||
.current_dir("tests/fixture/success/")
|
.current_dir("tests/fixture/success/")
|
||||||
.assert()
|
.assert()
|
||||||
.success();
|
.success();
|
||||||
|
@ -74,7 +74,7 @@ fn run_single_test_success() {
|
||||||
fn run_single_test_failure() {
|
fn run_single_test_failure() {
|
||||||
Command::cargo_bin("rustlings")
|
Command::cargo_bin("rustlings")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.args(&["r", "testFailure"])
|
.args(&["run", "testFailure"])
|
||||||
.current_dir("tests/fixture/failure/")
|
.current_dir("tests/fixture/failure/")
|
||||||
.assert()
|
.assert()
|
||||||
.code(1);
|
.code(1);
|
||||||
|
@ -84,7 +84,7 @@ fn run_single_test_failure() {
|
||||||
fn run_single_test_not_passed() {
|
fn run_single_test_not_passed() {
|
||||||
Command::cargo_bin("rustlings")
|
Command::cargo_bin("rustlings")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.args(&["r", "testNotPassed.rs"])
|
.args(&["run", "testNotPassed.rs"])
|
||||||
.current_dir("tests/fixture/failure/")
|
.current_dir("tests/fixture/failure/")
|
||||||
.assert()
|
.assert()
|
||||||
.code(1);
|
.code(1);
|
||||||
|
@ -94,7 +94,7 @@ fn run_single_test_not_passed() {
|
||||||
fn run_single_test_no_filename() {
|
fn run_single_test_no_filename() {
|
||||||
Command::cargo_bin("rustlings")
|
Command::cargo_bin("rustlings")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.arg("r")
|
.arg("run")
|
||||||
.current_dir("tests/fixture/")
|
.current_dir("tests/fixture/")
|
||||||
.assert()
|
.assert()
|
||||||
.code(1);
|
.code(1);
|
||||||
|
@ -104,7 +104,7 @@ fn run_single_test_no_filename() {
|
||||||
fn run_single_test_no_exercise() {
|
fn run_single_test_no_exercise() {
|
||||||
Command::cargo_bin("rustlings")
|
Command::cargo_bin("rustlings")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.args(&["r", "compNoExercise.rs"])
|
.args(&["run", "compNoExercise.rs"])
|
||||||
.current_dir("tests/fixture/failure")
|
.current_dir("tests/fixture/failure")
|
||||||
.assert()
|
.assert()
|
||||||
.code(1);
|
.code(1);
|
||||||
|
@ -114,7 +114,7 @@ fn run_single_test_no_exercise() {
|
||||||
fn get_hint_for_single_test() {
|
fn get_hint_for_single_test() {
|
||||||
Command::cargo_bin("rustlings")
|
Command::cargo_bin("rustlings")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.args(&["h", "testFailure"])
|
.args(&["hint", "testFailure"])
|
||||||
.current_dir("tests/fixture/failure")
|
.current_dir("tests/fixture/failure")
|
||||||
.assert()
|
.assert()
|
||||||
.code(0)
|
.code(0)
|
||||||
|
@ -131,10 +131,15 @@ fn all_exercises_require_confirmation() {
|
||||||
file.read_to_string(&mut s).unwrap();
|
file.read_to_string(&mut s).unwrap();
|
||||||
s
|
s
|
||||||
};
|
};
|
||||||
source.matches("// I AM NOT DONE").next().expect(&format!(
|
source
|
||||||
"There should be an `I AM NOT DONE` annotation in {:?}",
|
.matches("// I AM NOT DONE")
|
||||||
path
|
.next()
|
||||||
));
|
.unwrap_or_else(|| {
|
||||||
|
panic!(
|
||||||
|
"There should be an `I AM NOT DONE` annotation in {:?}",
|
||||||
|
path
|
||||||
|
)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,7 +147,7 @@ fn all_exercises_require_confirmation() {
|
||||||
fn run_compile_exercise_does_not_prompt() {
|
fn run_compile_exercise_does_not_prompt() {
|
||||||
Command::cargo_bin("rustlings")
|
Command::cargo_bin("rustlings")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.args(&["r", "pending_exercise"])
|
.args(&["run", "pending_exercise"])
|
||||||
.current_dir("tests/fixture/state")
|
.current_dir("tests/fixture/state")
|
||||||
.assert()
|
.assert()
|
||||||
.code(0)
|
.code(0)
|
||||||
|
@ -153,7 +158,7 @@ fn run_compile_exercise_does_not_prompt() {
|
||||||
fn run_test_exercise_does_not_prompt() {
|
fn run_test_exercise_does_not_prompt() {
|
||||||
Command::cargo_bin("rustlings")
|
Command::cargo_bin("rustlings")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.args(&["r", "pending_test_exercise"])
|
.args(&["run", "pending_test_exercise"])
|
||||||
.current_dir("tests/fixture/state")
|
.current_dir("tests/fixture/state")
|
||||||
.assert()
|
.assert()
|
||||||
.code(0)
|
.code(0)
|
||||||
|
@ -164,7 +169,7 @@ fn run_test_exercise_does_not_prompt() {
|
||||||
fn run_single_test_success_with_output() {
|
fn run_single_test_success_with_output() {
|
||||||
Command::cargo_bin("rustlings")
|
Command::cargo_bin("rustlings")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.args(&["--nocapture", "r", "testSuccess"])
|
.args(&["--nocapture", "run", "testSuccess"])
|
||||||
.current_dir("tests/fixture/success/")
|
.current_dir("tests/fixture/success/")
|
||||||
.assert()
|
.assert()
|
||||||
.code(0)
|
.code(0)
|
||||||
|
@ -175,7 +180,7 @@ fn run_single_test_success_with_output() {
|
||||||
fn run_single_test_success_without_output() {
|
fn run_single_test_success_without_output() {
|
||||||
Command::cargo_bin("rustlings")
|
Command::cargo_bin("rustlings")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.args(&["r", "testSuccess"])
|
.args(&["run", "testSuccess"])
|
||||||
.current_dir("tests/fixture/success/")
|
.current_dir("tests/fixture/success/")
|
||||||
.assert()
|
.assert()
|
||||||
.code(0)
|
.code(0)
|
||||||
|
@ -192,26 +197,6 @@ fn run_rustlings_list() {
|
||||||
.success();
|
.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn run_rustlings_list_conflicting_display_options() {
|
|
||||||
Command::cargo_bin("rustlings")
|
|
||||||
.unwrap()
|
|
||||||
.args(&["list", "--names", "--paths"])
|
|
||||||
.current_dir("tests/fixture/success")
|
|
||||||
.assert()
|
|
||||||
.failure();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn run_rustlings_list_conflicting_solve_options() {
|
|
||||||
Command::cargo_bin("rustlings")
|
|
||||||
.unwrap()
|
|
||||||
.args(&["list", "--solved", "--unsolved"])
|
|
||||||
.current_dir("tests/fixture/success")
|
|
||||||
.assert()
|
|
||||||
.failure();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn run_rustlings_list_no_pending() {
|
fn run_rustlings_list_no_pending() {
|
||||||
Command::cargo_bin("rustlings")
|
Command::cargo_bin("rustlings")
|
||||||
|
@ -231,10 +216,7 @@ fn run_rustlings_list_both_done_and_pending() {
|
||||||
.current_dir("tests/fixture/state")
|
.current_dir("tests/fixture/state")
|
||||||
.assert()
|
.assert()
|
||||||
.success()
|
.success()
|
||||||
.stdout(
|
.stdout(predicates::str::contains("Done").and(predicates::str::contains("Pending")));
|
||||||
predicates::str::contains("Done")
|
|
||||||
.and(predicates::str::contains("Pending"))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -258,4 +240,3 @@ fn run_rustlings_list_without_done() {
|
||||||
.success()
|
.success()
|
||||||
.stdout(predicates::str::contains("Done").not());
|
.stdout(predicates::str::contains("Done").not());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue