Compare commits

...

247 commits
4.1.0 ... main

Author SHA1 Message Date
red 84bb490545 PARTIALLY SOLVED 2021-07-07 21:03:42 +01:00
red aa2ce0ee19 SOLVED 2021-07-07 21:02:31 +01:00
red f1bf7b5735 UNSOLVED 2021-07-07 20:58:36 +01:00
red f81fe2b60c Delete excercies 2021-07-07 20:57:20 +01:00
red 5b989095cd Update 'README.md' 2021-07-07 19:49:15 +00:00
marisa cdd8e19716
Merge pull request from rust-lang/all-contributors/add-cseltol
docs: add cseltol as a contributor for doc
2021-07-05 18:57:05 +02:00
allcontributors[bot] 91d86a1de9
docs: update .all-contributorsrc [skip ci] 2021-07-05 16:56:57 +00:00
allcontributors[bot] 6a10f900b4
docs: update README.md [skip ci] 2021-07-05 16:56:56 +00:00
marisa 9b9a89c79a
Merge pull request from cseltol/main
fix(installation): first PowerShell command
2021-07-05 18:56:34 +02:00
marisa 123e6426d1
Merge pull request from kolbma/exercise-clippy1-hint-390
chore: clippy1 hint enhancement
2021-06-30 12:10:02 +02:00
marisa 427ec6b2e4
Merge pull request from rust-lang/all-contributors/add-jazzplato
docs: add jazzplato as a contributor for code
2021-06-30 12:06:16 +02:00
allcontributors[bot] 03dcb582e6
docs: update .all-contributorsrc [skip ci] 2021-06-30 10:06:07 +00:00
allcontributors[bot] 1043a06124
docs: update README.md [skip ci] 2021-06-30 10:06:06 +00:00
Richthofen d20e413a68
feat(cli): Add "next" to run the next unsolved exercise. ()
* Add "run next" to run the next unsolved exercise.

* Fix a grammar error in the message.

* Update README.md with the suggested change

Co-authored-by: marisa <mokou@fastmail.com>

* Update the README.md for "rustlings hint next".

Co-authored-by: marisa <mokou@fastmail.com>
2021-06-30 12:05:49 +02:00
arlecchino 9bf4c5e8df
chore: clippy1 hint enhancement
Added some explanation and links about floating point representation and to use the clippy suggestion. (fixes )
2021-06-29 20:47:32 +02:00
marisa 633303d4b8
Merge pull request from kolbma/exercise-iterator3-hint
chore: Update hint of iterators3
2021-06-29 13:49:17 +02:00
arlecchino a4a1098766
Update info.toml
Co-authored-by: marisa <mokou@fastmail.com>
2021-06-29 13:41:16 +02:00
marisa 0bd459dcac
Merge pull request from rust-lang/all-contributors/add-kolbma
docs: add kolbma as a contributor for doc
2021-06-29 12:46:49 +02:00
allcontributors[bot] 3b4514b686
docs: update .all-contributorsrc [skip ci] 2021-06-29 10:46:41 +00:00
allcontributors[bot] 2e05606edc
docs: update README.md [skip ci] 2021-06-29 10:46:40 +00:00
marisa c8c1b87a01
Merge pull request from kolbma/git-clone-release-tag
docs: Faster git clone command
2021-06-29 12:46:28 +02:00
arlecchino 34ea029df8
chore: Update hint of iterators3
`collect()` needs some hint for standard_library_types/iterators3 exercise with doc link for understanding different return types via `FromIterator`.
2021-06-29 12:03:18 +02:00
arlecchino 3a4433d5a2
docs: Faster git clone command
Clone only release tag without history
2021-06-28 17:08:53 +02:00
marisa de6c45ad24
Merge pull request from rust-lang/all-contributors/add-hyperparabolic
docs: add hyperparabolic as a contributor for code
2021-06-24 14:18:02 +02:00
allcontributors[bot] fadade8592
docs: update .all-contributorsrc [skip ci] 2021-06-24 12:17:32 +00:00
allcontributors[bot] d91044f3a2
docs: update README.md [skip ci] 2021-06-24 12:17:31 +00:00
marisa a3ea37b76e
Merge pull request from tlyu/iterators5-trait-tweak
fix(iterators5): derive Clone, Copy
2021-06-24 14:17:05 +02:00
marisa ec63cadadb
Merge pull request from tlyu/errors-rework
feature: improve error_handling exercises
2021-06-24 14:12:34 +02:00
marisa 84d8305730
Merge pull request from rust-lang/all-contributors/add-kayuapi
docs: add kayuapi as a contributor for content
2021-06-24 14:10:33 +02:00
allcontributors[bot] 73777980f1
docs: update .all-contributorsrc [skip ci] 2021-06-24 12:10:24 +00:00
allcontributors[bot] 75788b1148
docs: update README.md [skip ci] 2021-06-24 12:10:23 +00:00
marisa dd9b2ddc89
Merge pull request from kayuapi/patch-1
fix(variables5): confine the answer further
2021-06-24 14:10:02 +02:00
Taylor Yu b7ddd09fab address review feedback
Adjust error text and naming to conform with best practices.
Use `map_err()` instead of `or()`. Wrap lower-level errors instead of
ignoring their details.

Also, don't "cheat" by bypassing the `new()` function in tests.

Fix a dangling reference in the try_from_into hints.
2021-06-09 23:27:53 -05:00
ZC 48ffcbd2c4
fix(variables5): confine the answer further
let mut number = 3; can lead to a correct answer, so the comment helps to direct the users to the intended answer.
2021-06-07 18:22:55 +08:00
Taylor Yu 68d3ac567c feature: improve error_handling exercises
Add new exercises errors5 and errors6, to introduce boxed errors and
custom error enums more gently. Delete errorsn, because it tried to do
too much too soon.
2021-06-06 23:08:57 -05:00
Taylor Yu 50ab289da6 fix: rename result1 to errors4
Also put it in the ERROR HANDLING section where it probably belongs.
2021-06-06 23:08:54 -05:00
Taylor Yu 4e079fdd08 chore(iterators5): conciseness hint 2021-06-06 17:45:35 -05:00
Taylor Yu 91fc9e3118 fix(iterators5): derive Clone, Copy
To allow more flexibility in solutions, derive `Clone` and `Copy`
for `Progress`.
2021-06-06 17:38:02 -05:00
marisa a2f0401c4c
Merge pull request from tlyu/move-semantics5-fixes
fix: move_semantics5 hints
2021-05-23 15:41:56 +02:00
Taylor Yu 1b85828548 fix: move_semantics5 hints
Improve the hints for move_semantics5, as well as the explanatory
comments in the code.

Previously, it was not clear what possible changes were allowed.
It seems that reordering the statements might be the intended solution.
The previous comment about not "adding newlines" doesn't make sense,
so treating it as "adding new lines" makes it more clear.
2021-05-22 22:09:58 -05:00
Taylor Yu 4c46e5e1a3 chore: minor typos in move_semantics5 hints 2021-05-22 21:56:14 -05:00
marisa 4da9e7ee29
Merge pull request from rust-lang/all-contributors/add-sateeshkumarb
docs: add sateeshkumarb as a contributor
2021-05-17 14:11:15 +02:00
allcontributors[bot] 72e615aa7a
docs: update .all-contributorsrc [skip ci] 2021-05-17 12:11:05 +00:00
allcontributors[bot] cd02abc481
docs: update README.md [skip ci] 2021-05-17 12:11:04 +00:00
Sateesh 399ab328d8
feat: Add move_semantics5 exercise. ()
* feat: Add move_semantics5 exercise.

* feat: Add option3 exercise

* Address review comments. Fix typos, sentence formatting.

* Remove unwanted newline.

* Address review comments: make comment inline, fix format in print.
2021-05-17 14:10:40 +02:00
marisa 809ec2ce01
Merge pull request from tlyu/dyn-error-hints
fix(try_from_into, from_str): hints for dyn Error
2021-05-17 14:09:44 +02:00
Taylor Yu 11d2cf0d60 fix(try_from_into, from_str): hints for dyn Error
Add hints about how to return the correct type for functions that
return `Result<_, Box<dyn Error>`. Some feedback from Discord suggests
that people run into trouble with that.
2021-05-15 14:01:17 -05:00
marisa dbb2624403
Merge pull request from juanprq/main
fix: remove trailing whitespace
2021-05-13 17:20:47 +02:00
Juan Pablo Ramirez 4d4fa77459 fix: remove trailing whitespaces from iterators1 2021-05-12 10:20:07 -05:00
Juan Pablo Ramirez 3145794084 fix: add hints to generics1 and generics2 exercises 2021-05-11 14:50:05 -05:00
Juan Pablo Ramirez d9b69bd1a0 fix: remove trailing whitespace 2021-05-09 17:58:54 -05:00
marisa 7cd635fa84
Merge pull request from rust-lang/all-contributors/add-PiDelport
docs: add PiDelport as a contributor
2021-05-01 12:12:51 +02:00
allcontributors[bot] ce40e201f0
docs: update .all-contributorsrc [skip ci] 2021-05-01 10:12:43 +00:00
allcontributors[bot] 404f3ef465
docs: update README.md [skip ci] 2021-05-01 10:12:42 +00:00
marisa e1be594fdd
Merge pull request from PiDelport/patch-1
style(standard_library_types): stray line break
2021-05-01 12:12:29 +02:00
Pi Delport 9569c9a9e7
style(standard_library_types): stray line break 2021-04-29 23:31:26 +02:00
marisa 91530f5716
Merge pull request from maartentibau/quiz1_add_explicit_test_40
chore: Update quiz1.rs add explicit test for 40
2021-04-27 10:20:50 +02:00
Maarten Tibau 650b1dee54
chore: Update quiz1.rs add explicit test for 40 2021-04-25 19:02:50 +02:00
marisa 6b6dc9dd48
Merge pull request from rust-lang/all-contributors/add-stoiandan
docs: add stoiandan as a contributor
2021-04-24 17:36:48 +02:00
allcontributors[bot] 3a9ec4192d
docs: update .all-contributorsrc [skip ci] 2021-04-24 15:36:39 +00:00
allcontributors[bot] 4f7dbbd2c3
docs: update README.md [skip ci] 2021-04-24 15:36:38 +00:00
marisa 8c37db1a23
Merge pull request from stoiandan/main
updated README.md; specify need for admin rights
2021-04-24 17:36:19 +02:00
Dan Stoian c6b7ad8878 updated README.md; specify need for admin rights 2021-04-24 18:32:13 +03:00
mokou 84461c20cb release: 4.4.0 2021-04-24 11:57:00 +02:00
marisa 3cddda56fc
Merge pull request from Zerotask/add-hint-corresponding-readme
chore(watch): add hint for the exercises README.md
2021-04-24 11:46:25 +02:00
marisa 37f3069a67
Merge pull request from Zerotask/update-dependencies
chore(deps): update cargo dependencies
2021-04-24 11:45:56 +02:00
marisa 2b2fbe918e
Merge pull request from Zerotask/update-exercises-readme
docs(exercises): consistent excersises README.md files
2021-04-24 11:45:37 +02:00
Zerotask cf42ddc449
chore(watch): add hint for the exercises README.md
rustlings watch will now show an additional hint for the corresponding README.me
2021-04-23 20:28:55 +02:00
Zerotask eefa656232
chore(deps): update cargo dependencies 2021-04-23 20:07:32 +02:00
Zerotask 249ad44cc0
docs(exercises): updated all exercises readme files
all exercises readme files now have a unified structure and a description
2021-04-23 19:54:31 +02:00
marisa 54804e344d
Merge pull request from Zerotask/add-further-help-for-generics3
docs(generics): add bounds help
2021-04-23 15:05:00 +02:00
marisa 1c334de6fd
Merge pull request from Zerotask/add-further-help-to-error-excersis
docs(errors): add additional help for Result/Boxing
2021-04-23 15:04:47 +02:00
Zerotask f253103a31
docs(generics): add bounds help
add help for bounds provided by the rust by example book
2021-04-22 22:11:04 +02:00
Zerotask 1120db57a6
docs(errors): add additional help for Result/Boxing
add additional help information provided by the rust by example book
2021-04-22 21:32:29 +02:00
marisa afa661cff4
Merge pull request from rust-lang/feat/declap
feat: Replace clap with argh
2021-04-21 16:33:07 +02:00
mokou 347f30bd86 fix(main): Let find_exercise work with borrows 2021-04-21 16:21:56 +02:00
marisa 127773f3f5
Merge pull request from rust-lang/all-contributors/add-bmacer
docs: add bmacer as a contributor
2021-04-21 14:50:37 +02:00
allcontributors[bot] 8d0490bd70
docs: update .all-contributorsrc [skip ci] 2021-04-21 12:50:27 +00:00
allcontributors[bot] 293dfb35d5
docs: update README.md [skip ci] 2021-04-21 12:50:26 +00:00
Brandon Macer 81be404487
feat(arc1): Add more details to description and hint ()
Co-authored-by: bmacer <bmacer@cisco.com>
Co-authored-by: marisa <mokou@fastmail.com>
Co-authored-by: Roberto Vidal <vidal.roberto.j@gmail.com>
2021-04-21 14:50:03 +02:00
mokou 6177b6e126 chore: Fix integration tests 2021-04-21 14:47:53 +02:00
marisa 79cc657917
Merge pull request from apogeeoak/iterator
Added iterators5.rs exercise.
2021-04-21 10:10:50 +02:00
mokou 7928122fce feat: Replace clap with argh
I’ve been wanting to do this for a while, but always procrastinated on it. We’ve been using Clap since the 2.0 rewrite, but Clap is known to be a fairly heavy library. Since Rustlings is usually peoples’ first contact with a Rust compilation, I think it’s in our best interests that this complation is as fast as possible. In effect, replacing Clap with the smaller, structopt-style `argh` reduces the amount of crates needing to be compiled from 82 to 60.

I also think this makes the code way easier to read, we don’t need to use Clap’s methods anymore, but can switch over to using pure Rust methods, e.g., switches are booleans, options are Option<String>s or the like, and subcommands are just structs.
2021-04-21 10:08:26 +02:00
apogeeoak 9c88ea9126 Improved iterators5.rs explanation. 2021-04-20 18:55:04 -04:00
marisa 2b766ef9f9
Merge pull request from apogeeoak/iterator2
Moved iterators2.rs errors out of tests.
2021-04-20 11:24:10 +02:00
marisa bd3d9ac9d5
Merge pull request from apogeeoak/iterator3
Enabled iterators3.rs to run without commented out tests.
2021-04-20 11:22:39 +02:00
marisa aa0db8379c
Merge pull request from rust-lang/all-contributors/add-hongshaoyang
docs: add hongshaoyang as a contributor
2021-04-20 11:19:49 +02:00
allcontributors[bot] eadd41a9ec
docs: update .all-contributorsrc [skip ci] 2021-04-20 09:19:39 +00:00
allcontributors[bot] fab2eb9833
docs: update README.md [skip ci] 2021-04-20 09:19:38 +00:00
Shao Yang Hong 6bd791f2f4
fix(structs): Add 5.3 to structs/README ()
Co-authored-by: Shao Yang Hong <shaoyang.hong@ninjavan.co>
2021-04-20 11:19:24 +02:00
marisa ec5f80dce1
Merge pull request from rust-lang/all-contributors/add-k12ish
docs: add k12ish as a contributor
2021-04-20 11:18:32 +02:00
allcontributors[bot] 65cdc856ae
docs: update .all-contributorsrc [skip ci] 2021-04-20 09:18:23 +00:00
allcontributors[bot] 472f61485e
docs: update README.md [skip ci] 2021-04-20 09:18:22 +00:00
k12ish b4de659438
fix(option2): Rename uninformative variables ()
Renaming uninformative names like `optional_value`, `value`, `optional_values_vec` and `value` helps users distinguish between the two parts of the task.
2021-04-20 11:18:05 +02:00
marisa a37a8818c8
Merge pull request from rust-lang/all-contributors/add-arthas168
docs: add arthas168 as a contributor
2021-04-20 11:16:25 +02:00
allcontributors[bot] bdf01aa174
docs: update .all-contributorsrc [skip ci] 2021-04-20 09:16:16 +00:00
allcontributors[bot] a941c69f09
docs: update README.md [skip ci] 2021-04-20 09:16:15 +00:00
Pete Pavlovski 72aaa15e6a
fix(hashmap2): Update incorrect assertion ()
The test description says "at least five types of fruit", but the test itself is checking for exactly five types of fruit, which was a bit misleading for newcomers like me :) 

A simple change from "==" to ">=" should do the trick and successfully check for the "at least" condition.
2021-04-20 11:15:49 +02:00
marisa 3a06de71a8
Merge pull request from Zerotask/list-command-added-to-readme
docs: added hint for rustlings list command
2021-04-20 11:10:38 +02:00
marisa 5e2b39a5c1
Merge pull request from rust-lang/all-contributors/add-Zerotask
docs: add Zerotask as a contributor
2021-04-20 11:09:41 +02:00
allcontributors[bot] 63c942233e
docs: update .all-contributorsrc [skip ci] 2021-04-20 09:09:31 +00:00
allcontributors[bot] 2612edc133
docs: update README.md [skip ci] 2021-04-20 09:09:30 +00:00
marisa e2ce9f42b5
Merge pull request from Zerotask/list-command-progress-info
feat(list): added progress info
2021-04-20 11:09:14 +02:00
Patrick Hintermayer 1c6f7e4b7b
feat(list): updated progress percentage 2021-04-19 09:39:05 +02:00
Zerotask e2c41903ad
docs: added hint for rustlings list command
Added hint for `rustlings list` to the "Doing exercises" section.
2021-04-18 16:07:30 +02:00
Zerotask bd48544e25
style: formatted files with rustfmt 2021-04-18 15:40:47 +02:00
Zerotask c0e3daacaf
feat(list): added progress info
Added a progress info at the bottom of the list for command: rustlings list

closes 
2021-04-18 15:37:41 +02:00
Abdou Seck f2ad3a6a0b
Merge pull request from WowSuchRicky/main
Rename 'Lichi' to 'Lychee' in the fruit example
2021-04-13 10:40:07 -04:00
Abdou Seck caf921a01f
Merge pull request from Morsicus/fix/collections-exercises-naming
Update collections exercises naming
2021-04-13 10:39:18 -04:00
WowSuchRicky b790bafc02 Rename lichi to lychee in the fruit example 2021-04-09 14:08:02 -07:00
Abdou Seck ad3cd54cce
Merge pull request from rust-lang/all-contributors/add-tlyu
docs: add tlyu as a contributor
2021-04-05 07:27:42 -04:00
allcontributors[bot] 1a6a725f88
docs: update .all-contributorsrc [skip ci] 2021-04-05 11:27:17 +00:00
allcontributors[bot] 1ad20d94ff
docs: update README.md [skip ci] 2021-04-05 11:27:16 +00:00
Abdou Seck 995c6f0fb1
Merge pull request from tlyu/trait-obj-tryfrom
fix: use trait objects for try_from_into and from_str
2021-04-05 07:26:19 -04:00
Taylor Yu c3e7b83178 fix: use trait objects for from_str
Use `Box<dyn error::Error>` to allow solutions to use `?` to propagate 
errors.
2021-04-04 18:56:10 -05:00
Taylor Yu 2e93a588e0 fix: use trait objects for try_from_into
Use `Box<dyn error::Error>` to allow solutions to use `?` to propagate
errors.  In the tests, explicitly check `is_ok()` instead of trying to
force the error type to `String` (or other `PartialEq` type) using
`assert_eq!()`.
2021-04-04 12:41:32 -05:00
marisa 9aeca3f97e
Merge pull request from rust-lang/all-contributors/add-flakolefluk
docs: add flakolefluk as a contributor
2021-04-04 09:44:02 +02:00
allcontributors[bot] 2193fff4bb
docs: update .all-contributorsrc [skip ci] 2021-04-04 07:43:51 +00:00
allcontributors[bot] aec2c65c63
docs: update README.md [skip ci] 2021-04-04 07:43:50 +00:00
Ignacio Le Fluk a6509cc4d5
fix(functions3): improve function argument type () 2021-04-04 09:43:25 +02:00
marisa a02b279750
chore: Provide a working Windows installation link 2021-03-23 09:10:40 +01:00
marisa ece841f5ce
Merge pull request from rust-lang/all-contributors/add-blerchy
docs: add blerchy as a contributor
2021-03-22 13:37:10 +01:00
allcontributors[bot] 2a6e4dc8a6
docs: update .all-contributorsrc [skip ci] 2021-03-22 12:37:02 +00:00
allcontributors[bot] c163011cc0
docs: update README.md [skip ci] 2021-03-22 12:37:01 +00:00
marisa b350945a16
Merge pull request from blerchy/feat/no-emoji
Replace emojis when NO_EMOJI env variable present
2021-03-22 13:36:26 +01:00
marisa 1ef368a69d
Merge pull request from rust-lang/new-install-urls
chore: Update install URLs
2021-03-21 16:35:44 +01:00
marisa 8dc587b01a
chore: Update install URLs 2021-03-21 16:34:21 +01:00
allcontributors[bot] 550c4293ed
docs: add chapeupreto as a contributor ()
* docs: update README.md [skip ci]

* docs: update .all-contributorsrc [skip ci]

Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
2021-03-20 21:13:35 +01:00
Rod Elias 3df094713f
chore: capitalize c letter
By capitalizing the `c` letter it makes clear that we're talking about the C programming language.
2021-03-20 21:12:49 +01:00
Matt Lebl 01e7f27aa6 refactor: change from match to if for NO_EMOJI 2021-03-20 11:53:40 -07:00
Matt Lebl 8d62a99637 feat: Replace emojis when NO_EMOJI env variable present 2021-03-19 02:16:07 -07:00
Mickael Fortunato ab9995e76e doc: Update collections exercises instruction to match the standard naming 2021-03-18 19:11:15 +01:00
Mickael Fortunato bef39b1259 fix(collections): Naming exercises for vectors and hashmap 2021-03-18 19:11:04 +01:00
Pascal H 0d894e6ff7
fix(quiz3): Force an answer to Q2 ()
Add also an example of unimplemented!() macro.
2021-03-16 10:14:25 +01:00
allcontributors[bot] be9510539e
docs: add hpwxf as a contributor ()
* docs: update README.md [skip ci]

* docs: update .all-contributorsrc [skip ci]

Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
2021-03-15 09:14:41 +01:00
Pascal H 3bce2ef8d6
chore: clarify collections documentation
C++ `map` is more like BTreeMap.

`unordered_map` in C++(11) is the equivalent of `HashMap` in Rust.
(+ additional like for references).
2021-03-15 09:14:12 +01:00
Ivan Nerazumov aa9a943ddf
fix(installation): first PowerShell command
ExecutionPolicy to RemoteSigned command was fixed because the old command was getting denied access to change the Execution Policy property
2021-03-13 18:45:52 +07:00
Darius Wiles ebdb66c7bf
fix(structs2): correct grammar in hint () 2021-03-13 12:14:44 +01:00
Darius Wiles 9f3e8c2dde
fix(structs3): reword heading comment () 2021-03-13 12:14:02 +01:00
apogeeoak 96c56ab08a
chore: changed errors3 mode from test to compile 2021-03-12 20:04:29 +01:00
allcontributors[bot] 04dbf03ace
docs: add cadolphs as a contributor ()
* docs: update README.md [skip ci]

* docs: update .all-contributorsrc [skip ci]

Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
2021-03-12 18:37:58 +01:00
cadolphs 05a753fe63
fix: add check to prevent naive implementation of is_international
* fix(structs3): Add check to prevent naive implementation

* chore(structs3): Add a missed newline after the test I added
2021-03-12 18:36:35 +01:00
allcontributors[bot] 815edb7003
docs: add cjwyett as a contributor ()
* docs: update README.md [skip ci]

* docs: update .all-contributorsrc [skip ci]

Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
2021-03-12 15:39:40 +01:00
Cyrus Wyett 5157f56875
chore: fix typo
is however some --> are however some
2021-03-12 15:38:28 +01:00
allcontributors[bot] 3f5abca215
docs: add circumspect as a contributor
* docs: update README.md [skip ci]

* docs: update .all-contributorsrc [skip ci]

Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
2021-03-12 15:28:03 +01:00
circumspect 833df0b8b3
chore: fix typo
Co-authored-by: Chenkail <40770208+Chenkail@users.noreply.github.com>
2021-03-12 15:26:57 +01:00
marisa 6742860ea5
Merge pull request from rust-lang/all-contributors/add-Crell
docs: add Crell as a contributor
2021-02-25 11:21:11 +01:00
allcontributors[bot] 797e6d45c0
docs: update .all-contributorsrc [skip ci] 2021-02-25 10:20:54 +00:00
allcontributors[bot] 320de0d921
docs: update README.md [skip ci] 2021-02-25 10:20:53 +00:00
marisa 5eed505d74
Merge pull request from Crell/spelling-fix
fix: Spelling error
2021-02-25 11:20:39 +01:00
Larry Garfield 91ee27f22b
fix: Spelling error 2021-02-24 15:03:26 -06:00
Jirka Kremser 5f7c89f85d
fix(from_str): Correct typos
typos in the comments
2021-02-21 21:50:17 +01:00
apogeeoak c6712dfccd fix(iterators3): Enabled iterators3.rs to run without commented out tests. 2021-02-12 15:36:53 -05:00
apogeeoak baf4ba175b fix(iterators2): Moved errors out of tests.
Closes 
2021-02-11 21:24:32 -05:00
apogeeoak b29ea17ea9 feat: Added iterators5.rs exercise. 2021-02-10 18:03:29 -05:00
marisa ab57c26cf9
Merge pull request from apogeeoak/clippy
Updated source to follow clippy suggestions.
2021-02-10 10:37:13 +01:00
marisa 98e5e8835e
Merge pull request from rust-lang/all-contributors/add-apogeeoak
docs: add apogeeoak as a contributor
2021-02-10 10:36:57 +01:00
allcontributors[bot] f5158ece1a
docs: update .all-contributorsrc [skip ci] 2021-02-10 09:36:48 +00:00
allcontributors[bot] d65b4a9a93
docs: update README.md [skip ci] 2021-02-10 09:36:47 +00:00
marisa 8404947bc0
Merge pull request from apogeeoak/contributing
Fixed grammar in contributing.md.
2021-02-10 10:36:04 +01:00
apogeeoak 2e84f34cf3 chore: Updated source to follow clippy suggestions. 2021-02-09 18:21:18 -05:00
apogeeoak 726805f064 docs: Fixed grammar in contributing.md. 2021-02-09 17:43:53 -05:00
marisa b4a4138559
Merge pull request from rust-lang/all-contributors/add-tal-zvon
docs: add tal-zvon as a contributor
2021-02-07 12:22:49 +01:00
allcontributors[bot] f1d2b3a39a
docs: update .all-contributorsrc [skip ci] 2021-02-07 11:22:33 +00:00
allcontributors[bot] 1f9d006858
docs: update README.md [skip ci] 2021-02-07 11:22:32 +00:00
Tal cc266d7d80
fix(move_semantics4): Remove redundant "instead" () 2021-02-07 12:22:13 +01:00
marisa fff72afe2e
Merge pull request from rust-lang/all-contributors/add-jbaber
docs: add jbaber as a contributor
2021-01-30 17:12:39 +01:00
allcontributors[bot] c1abd13b5c
docs: update .all-contributorsrc [skip ci] 2021-01-30 16:12:28 +00:00
allcontributors[bot] 75802c14b2
docs: update README.md [skip ci] 2021-01-30 16:12:27 +00:00
John Baber-Lucero cddc1e86e7
fix(info): Fix typo ()
Co-authored-by: John Baber-Lucero <git@frundle.com>
2021-01-30 17:12:06 +01:00
fmoko 24ea42ce61
Merge pull request from rust-lang/all-contributors/add-jfchevrette
docs: add jfchevrette as a contributor
2021-01-22 13:11:43 +01:00
allcontributors[bot] 6102e612fa
docs: update .all-contributorsrc [skip ci] 2021-01-22 12:11:34 +00:00
allcontributors[bot] 52bde71166
docs: update README.md [skip ci] 2021-01-22 12:11:33 +00:00
Abdou Seck 15a79cfe9c
Merge pull request from jfchevrette/patch-1
Fix instructions(steps) for conversions/from_str exercice
2021-01-21 08:10:25 -05:00
Jean-Francois Chevrette 15e71535f3 fix(from_str): test for error instead of unwrap/should_panic 2021-01-21 07:55:22 -05:00
mokou 9f988bfe29 docs: Remove duplicate uninstallation section 2021-01-17 13:00:50 +01:00
fmoko e8d1baa4b5
Merge pull request from AbdouSeck/improve-list-command
feat(cli): Improve the list command with options, and then some
2021-01-17 12:37:58 +01:00
Abdou Seck 8bbe4ff138 feat(cli): Improve the list command with options, and then some
1.
`rustlings list` should now display more than just the exercise names.
Information such as file paths and exercises statuses should be displayed.
The `--paths` option limits the displayed fields to only the path names; while the `--names`
option limits the displayed fields to only exercise names.
You can also control which exercises are displayed, by using the `--filter` option, or
the `--solved` or `--unsolved` flags.

Some use cases:
- Fetching pending exercise files with the keyword "conversion" to pass to my editor:
```sh
vim $(rustlings list --filter "conversion" --paths --unsolved)
```

- Fetching exercise names with keyword "conversion" to pass to `rustlings run`:
```sh
for exercise in $(rustlings list --filter "conversion" --names)
do
    rustlings run ${exercise}
done
```

2.
This should also fix , and will likely fix , as well.
That bug mentioned in those issues has to do with the way the `watch` command handler fetches the pending exercises.
Going forward, the least recently updated exercises along with all the other exercises in a pending state are fetched.
2021-01-08 13:21:00 -05:00
Abdou Seck 0b9220c1fc Add looks_done method to Exercise to expose a resolution state 2021-01-08 13:21:00 -05:00
Abdou Seck 0d65753fdb
Merge pull request from lntuition/conversions_more_utc
feat(conversions): Add more unit tests to `from_str` and `from_into` exercises.
2021-01-08 13:18:24 -05:00
Sang-Heon Jeon 4f1374a6e7 feat(from_into) : add test for checking unnecessary trailing value 2021-01-09 00:08:38 +09:00
Sang-Heon Jeon 5a0521e92c feat(from_str) : add test for checking unnecessary trailing value 2021-01-09 00:07:13 +09:00
fmoko fea86c29d6
chore: Remove Readme GIF 2021-01-08 14:01:04 +01:00
fmoko 9c4614f7e6
Merge pull request from rust-lang/all-contributors/add-chrizel
docs: add chrizel as a contributor
2021-01-06 16:54:47 +01:00
allcontributors[bot] c24a78ae94
docs: update .all-contributorsrc [skip ci] 2021-01-06 15:54:34 +00:00
allcontributors[bot] 621816fb56
docs: update README.md [skip ci] 2021-01-06 15:54:33 +00:00
fmoko cfae54d361
Merge pull request from chrizel/patch-1
fix(threads1): line number correction
2021-01-06 16:54:16 +01:00
Christian Zeller 7857b0a689
fix(threads1): line number correction 2021-01-06 13:47:20 +01:00
Marius Ungureanu 10965920fb
fix(move_semantics4): Small readbility improvement ()
* Small readbility improvement move_semantics4 doc

* Remove `an` as it refers to the argument
2021-01-06 10:12:33 +01:00
fmoko d2e7ecabd8
Merge pull request from rust-lang/all-contributors/add-wsh
docs: add wsh as a contributor
2021-01-04 14:12:24 +01:00
fmoko 5772589dc3
Merge pull request from wsh/docfixes
docs: mention flatten in the options2 hint
2021-01-04 14:12:11 +01:00
allcontributors[bot] 6df08b411b
docs: update .all-contributorsrc [skip ci] 2021-01-04 13:12:11 +00:00
allcontributors[bot] c355ac6593
docs: update README.md [skip ci] 2021-01-04 13:12:10 +00:00
Will Hayworth e9b42bbc2a docs: mention flatten in the options2 hint 2021-01-03 03:42:39 -08:00
Abdou Seck 1283aa3bd8 Merge pull request from RoelofWobben/ghost-RoelofWobben-patch-1
fix: Update README.md for Windows users to exclude the rustlings directory
from the list of directories scanned by Anti-Virus programs.
2020-12-31 11:13:03 -05:00
RoelofWobben ff6cba7205 Update README.md 2020-12-31 10:57:37 -05:00
fmoko d0107f7921
Merge pull request from xehpuk/patch-1
fix: typo in default out text
2020-12-31 16:12:13 +01:00
xehpuk 644c49f1e0
fix: typo in default out text 2020-12-30 22:56:04 +01:00
mokou a303d508cf release: 4.3.0 2020-12-29 11:39:26 +01:00
mokou 44d39112ff feat: Rewrite default out text
This has been in place for a long time now, before we had an install
script, so it ended up repeating a bunch of the same things that the
install script does automatically. I rewrote it so that it gives more
helpful information about how you're supposed to do Rustlings.
Hopefully this will reduce the number of "I started Rustlings and it
gave me an error" issues (no offense to anyone who opened one of those,
it was pretty unclear that it _wasn't_ an error).
2020-12-29 11:34:52 +01:00
mokou 28020d0c54 docs: Add note on uninstalling to README 2020-12-29 11:23:08 +01:00
Axel Viala 0ef95947cc
fix(functions2): Change signature to trigger precise error message: ()
Now trigger this error:
```
error: expected type, found `)`
  --> exercises/functions/functions2.rs:10:16
   |
10 | fn call_me(num:) {
   |                ^ expected type

```
2020-12-27 12:36:38 +01:00
allcontributors[bot] 4ac70a99ae
docs: add seancad as a contributor
* docs: update README.md [skip ci]

* docs: update .all-contributorsrc [skip ci]

Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
2020-12-15 08:33:47 +01:00
seancad bcf14cf677
fix: update structs README 2020-12-15 08:32:46 +01:00
fmoko 1dae782cd4
Merge pull request from JuliaCao/update_exec_order
fix: added missing exercises to info.toml
2020-12-13 02:30:57 +01:00
JuliaCao 90cfb6ff28 fix: added missing exercises to info.toml 2020-12-12 10:34:59 -08:00
allcontributors[bot] 26110da7ca
docs: add pcn as a contributor
* docs: update README.md [skip ci]

* docs: update .all-contributorsrc [skip ci]

Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
2020-12-08 10:12:57 +01:00
Peter N 30644c9a06
fix: gives a bit more context to magic number 2020-12-08 10:08:25 +01:00
JuliaCao 033bf1198f
feat: match exercise order to book chapters ()
Added exercise to book chapter mapping table to exercise README
2020-12-07 15:37:19 +01:00
fmoko cdc7d92e57
Merge pull request from tinkhauser/vec1_bugfix
fix(vec1): Have test compare every element in a and v
2020-12-06 15:09:45 +01:00
fmoko af0e3b8f17
Merge pull request from xakon/fix/try_from_into
feat(try_from_into): remove duplicate annotation
2020-12-03 18:23:48 +01:00
Christos Kontas 04f1d079aa feat(try_from_into): remove duplicate annotation 2020-12-03 17:51:30 +01:00
Jacob Tinkhauser 9b6c629397
fix(vec1): Have test compare every element in a and v
The previous test would stop comparing elements in array a and vec v upon reaching the last element of either. This resulted in the test passing even if v did not contain all the elements in a. This change to the test fixes that bug and should only pass if all the elements in a and v are present and equal.
2020-11-29 01:35:14 +00:00
fmoko 5aa467bef2
Merge pull request from wh5a/bugfix
fix(try_from_into): type error
2020-11-12 16:36:50 +01:00
fmoko af7ad27f89
chore: Remove buildkite build file 2020-11-12 09:50:55 +01:00
fmoko d6d57bfbb8
docs: Remove buildkite badge from README 2020-11-12 09:50:39 +01:00
Wei Hu 4f4cfcf3c3 fix(try_from_into): type error 2020-11-11 21:02:00 -08:00
Brock fa9f522b7f
feat: Crab? ()
Crab?
2020-11-11 23:06:14 +01:00
Caleb Webber 838f9f3008
feat: add "rustlings list" command 2020-11-10 18:36:19 +01:00
JP 96347df9df
fix(try_from_into): Update description ()
Description update
2020-11-08 19:30:40 +01:00
Brock 9334783da3
fix(structs1): Adjust wording ()
Co-authored-by: fmoko <mokou@posteo.de>
2020-11-08 10:31:45 +01:00
mokou 964b2a331d release: 4.2.0 2020-11-07 14:21:10 +01:00
fiplox 95ccd92616
feat(try_from_into): Add tests ()
Co-authored-by: Volodymyr Patuta <6977238-fiplox@users.noreply.gitlab.com>
2020-11-07 14:01:39 +01:00
JP 197d3a3d89
fix(iterators2): Update description ()
grammar fix in the description
2020-11-07 13:54:14 +01:00
fmoko a7ddd747ca
Merge pull request from seeplusplus/inotify-watch-error
fix: log error output when inotify limit is exceeded
2020-11-07 13:53:35 +01:00
Caleb Webber d61b4e5a13
fix: log error output when inotify limit is exceeded
closes 
2020-11-05 19:30:50 -05:00
allcontributors[bot] 68e646f8aa
docs: add seeplusplus as a contributor 2020-11-05 10:03:43 +01:00
Caleb Webber 21bfb2d477
fix(installation): Update the MinRustVersion
closes #577df

Co-authored-by: Caleb Webber <seeplusplus@users.noreply.github.com>
2020-11-05 09:59:25 +01:00
fmoko a9dae71188
Merge pull request from jrvidal/temp_file
fix: more unique temp_file
2020-10-31 12:57:33 +01:00
fmoko dd84cc5fd4
Merge pull request from rust-lang/all-contributors/add-sazid 2020-10-30 20:29:47 +01:00
allcontributors[bot] 51631f4c2e
docs: update .all-contributorsrc [skip ci] 2020-10-30 19:29:37 +00:00
allcontributors[bot] 535a8c8243
docs: update README.md [skip ci] 2020-10-30 19:29:36 +00:00
fmoko 7abfbd23d0
Merge pull request from sazid/main 2020-10-30 20:28:46 +01:00
sazid 633c00cf80 feat: Add HashMap exercises 2020-10-31 01:11:04 +06:00
sazid 0c12fa31c5 feat: Add Vec exercises 2020-10-31 01:10:49 +06:00
Roberto Vidal 5643ef05bc fix: more unique temp_file 2020-10-30 14:39:28 +01:00
fmoko f38f42f17d
Merge pull request from notmatt/mbs-fixups 2020-10-14 17:22:49 +02:00
Matthew Smillie 472d8592d6 fix(primitive_types6): remove 'unused doc comment' warning 2020-10-13 23:20:17 -07:00
Matthew Smillie 4fb230daf1 fix(primitive_types6): missing comma in test 2020-10-13 23:18:41 -07:00
Rastamo e6bde22f9c
chore: primitive_types6 mode changed to test ()
primitive_types6 exercise was changed to test yesterday, but info.toml file wasn't updated.
I think this change should fix it.
2020-10-11 14:00:03 +02:00
allcontributors[bot] cc5b9b772a
docs: add AnnikaCodes as a contributor ()
Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
Co-authored-by: fmoko <mokou@posteo.de>
2020-10-10 17:08:22 +02:00
allcontributors[bot] ded1474bbb
docs: add darnuria as a contributor ()
Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
2020-10-10 16:07:15 +02:00
Axel Viala 2b1fb2b739
feat(primitive_types6): Add a test ()
Co-authored-by: Annika <56906084+AnnikaCodes@users.noreply.github.com>
Co-authored-by: fmoko <mokou@posteo.de>
2020-10-10 16:04:19 +02:00
Ryan McQuen 18e0bfef1d
fix(quiz3): Second test is for odd numbers, not even. () 2020-10-10 13:11:57 +02:00
fmoko 3be760dc38
Merge pull request from rust-lang/all-contributors/add-ryanpcmcquen 2020-10-09 02:16:07 +02:00
allcontributors[bot] 29dd0b1e41
docs: update .all-contributorsrc [skip ci] 2020-10-09 00:15:54 +00:00
allcontributors[bot] e1fdfbb062
docs: update README.md [skip ci] 2020-10-09 00:15:53 +00:00
96 changed files with 2577 additions and 1707 deletions

View file

@ -591,6 +591,326 @@
"contributions": [
"content"
]
},
{
"login": "ryanpcmcquen",
"name": "Ryan McQuen",
"avatar_url": "https://avatars3.githubusercontent.com/u/772937?v=4",
"profile": "https://ryanpcmcquen.org",
"contributions": [
"code"
]
},
{
"login": "AnnikaCodes",
"name": "Annika",
"avatar_url": "https://avatars3.githubusercontent.com/u/56906084?v=4",
"profile": "https://github.com/AnnikaCodes",
"contributions": [
"review"
]
},
{
"login": "darnuria",
"name": "Axel Viala",
"avatar_url": "https://avatars1.githubusercontent.com/u/2827553?v=4",
"profile": "https://darnuria.eu",
"contributions": [
"code"
]
},
{
"login": "sazid",
"name": "Mohammed Sazid Al Rashid",
"avatar_url": "https://avatars1.githubusercontent.com/u/2370167?v=4",
"profile": "https://sazid.github.io",
"contributions": [
"content",
"code"
]
},
{
"login": "seeplusplus",
"name": "Caleb Webber",
"avatar_url": "https://avatars1.githubusercontent.com/u/17479099?v=4",
"profile": "https://codingthemsoftly.com",
"contributions": [
"maintenance"
]
},
{
"login": "pcn",
"name": "Peter N",
"avatar_url": "https://avatars2.githubusercontent.com/u/1056756?v=4",
"profile": "https://github.com/pcn",
"contributions": [
"maintenance"
]
},
{
"login": "seancad",
"name": "seancad",
"avatar_url": "https://avatars1.githubusercontent.com/u/47405611?v=4",
"profile": "https://github.com/seancad",
"contributions": [
"maintenance"
]
},
{
"login": "wsh",
"name": "Will Hayworth",
"avatar_url": "https://avatars3.githubusercontent.com/u/181174?v=4",
"profile": "http://willhayworth.com",
"contributions": [
"content"
]
},
{
"login": "chrizel",
"name": "Christian Zeller",
"avatar_url": "https://avatars3.githubusercontent.com/u/20802?v=4",
"profile": "https://github.com/chrizel",
"contributions": [
"content"
]
},
{
"login": "jfchevrette",
"name": "Jean-Francois Chevrette",
"avatar_url": "https://avatars.githubusercontent.com/u/3001?v=4",
"profile": "https://github.com/jfchevrette",
"contributions": [
"content",
"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,

View file

@ -1,3 +1,92 @@
<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>
## 4.3.0 (2020-12-29)
#### Features
* Rewrite default out text ([44d39112](https://github.com/rust-lang/rustlings/commit/44d39112ff122b29c9793fe52e605df1612c6490))
* match exercise order to book chapters (#541) ([033bf119](https://github.com/rust-lang/rustlings/commit/033bf1198fc8bfce1b570e49da7cde010aa552e3))
* Crab? (#586) ([fa9f522b](https://github.com/rust-lang/rustlings/commit/fa9f522b7f043d7ef73a39f003a9272dfe72c4f4))
* add "rustlings list" command ([838f9f30](https://github.com/rust-lang/rustlings/commit/838f9f30083d0b23fd67503dcf0fbeca498e6647))
* **try_from_into:** remove duplicate annotation ([04f1d079](https://github.com/rust-lang/rustlings/commit/04f1d079aa42a2f49af694bc92c67d731d31a53f))
#### Bug Fixes
* update structs README ([bcf14cf6](https://github.com/rust-lang/rustlings/commit/bcf14cf677adb3a38a3ac3ca53f3c69f61153025))
* added missing exercises to info.toml ([90cfb6ff](https://github.com/rust-lang/rustlings/commit/90cfb6ff28377531bfc34acb70547bdb13374f6b))
* gives a bit more context to magic number ([30644c9a](https://github.com/rust-lang/rustlings/commit/30644c9a062b825c0ea89435dc59f0cad86b110e))
* **functions2:** Change signature to trigger precise error message: (#605) ([0ef95947](https://github.com/rust-lang/rustlings/commit/0ef95947cc30482e63a7045be6cc2fb6f6dcb4cc))
* **structs1:** Adjust wording (#573) ([9334783d](https://github.com/rust-lang/rustlings/commit/9334783da31d821cc59174fbe8320df95828926c))
* **try_from_into:**
* type error ([4f4cfcf3](https://github.com/rust-lang/rustlings/commit/4f4cfcf3c36c8718c7c170c9c3a6935e6ef0618c))
* Update description (#584) ([96347df9](https://github.com/rust-lang/rustlings/commit/96347df9df294f01153b29d9ad4ba361f665c755))
* **vec1:** Have test compare every element in a and v ([9b6c6293](https://github.com/rust-lang/rustlings/commit/9b6c629397b24b944f484f5b2bbd8144266b5695))
<a name="4.2.0"></a>
## 4.2.0 (2020-11-07)
#### Features
* Add HashMap exercises ([633c00cf](https://github.com/rust-lang/rustlings/commit/633c00cf8071e1e82959a3010452a32f34f29fc9))
* Add Vec exercises ([0c12fa31](https://github.com/rust-lang/rustlings/commit/0c12fa31c57c03c6287458a0a8aca7afd057baf6))
* **primitive_types6:** Add a test (#548) ([2b1fb2b7](https://github.com/rust-lang/rustlings/commit/2b1fb2b739bf9ad8d6b7b12af25fee173011bfc4))
* **try_from_into:** Add tests (#571) ([95ccd926](https://github.com/rust-lang/rustlings/commit/95ccd92616ae79ba287cce221101e0bbe4f68cdc))
#### Bug Fixes
* log error output when inotify limit is exceeded ([d61b4e5a](https://github.com/rust-lang/rustlings/commit/d61b4e5a13b44d72d004082f523fa1b6b24c1aca))
* more unique temp_file ([5643ef05](https://github.com/rust-lang/rustlings/commit/5643ef05bc81e4a840e9456f4406a769abbe1392))
* **installation:** Update the MinRustVersion ([21bfb2d4](https://github.com/rust-lang/rustlings/commit/21bfb2d4777429c87d8d3b5fbf0ce66006dcd034))
* **iterators2:** Update description (#578) ([197d3a3d](https://github.com/rust-lang/rustlings/commit/197d3a3d8961b2465579218a6749b2b2cefa8ddd))
* **primitive_types6:**
* remove 'unused doc comment' warning ([472d8592](https://github.com/rust-lang/rustlings/commit/472d8592d65c8275332a20dfc269e7ac0d41bc88))
* missing comma in test ([4fb230da](https://github.com/rust-lang/rustlings/commit/4fb230daf1251444fcf29e085cee222a91f8a37e))
* **quiz3:** Second test is for odd numbers, not even. (#553) ([18e0bfef](https://github.com/rust-lang/rustlings/commit/18e0bfef1de53071e353ba1ec5837002ff7290e6))
<a name="4.1.0"></a>
## 4.1.0 (2020-10-05)

View file

@ -26,12 +26,12 @@ isn't really that complicated since the bulk of the work is done by `rustc`.
<a name="addex"></a>
### 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`.
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
...
+ [[exercises]]

835
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -1,11 +1,11 @@
[package]
name = "rustlings"
version = "4.1.0"
version = "4.4.0"
authors = ["Marisa <mokou@posteo.de>", "Carol (Nichols || Goulding) <carol.nichols@gmail.com>"]
edition = "2018"
[dependencies]
clap = "2.32.0"
argh = "0.1.4"
indicatif = "0.10.3"
console = "0.7.7"
notify = "4.0.15"

237
README.md
View file

@ -1,236 +1,3 @@
![crab pet](https://i.imgur.com/LbZJgmm.gif)
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
[![All Contributors](https://img.shields.io/badge/all_contributors-63-orange.svg?style=flat-square)](#contributors-)
<!-- ALL-CONTRIBUTORS-BADGE:END -->
# rustlings
# rustlings 🦀❤️ [![Build status](https://badge.buildkite.com/7af93d81dc522c67a1ec8e33ff5705861b1cb36360b774807f.svg)](https://buildkite.com/mokou/rustlings)
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.
## 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.1.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.
If you'd like to uninstall Rustlings, you can do so by invoking cargo and removing the rustlings directory:
```bash
cargo uninstall rustlings
rm -r rustlings/ # or on Windows: rmdir /s rustlings
```
## 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" width="100px;" alt=""/><br /><sub><b>Carol (Nichols &#124;&#124; 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" 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" width="100px;" alt=""/><br /><sub><b>Greg Leonard</b></sub></a><br /><a href="#content-greg-el" title="Content">🖋</a></td>
</tr>
</table>
<!-- markdownlint-enable -->
<!-- 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!
My solutions to rustlings excercises

View file

@ -1,5 +0,0 @@
steps:
- label: "Test with stable"
command: rustup run stable cargo test
- label: "Test with beta"
command: rustup run beta cargo test

View file

@ -1,19 +1,25 @@
Thanks for installing Rustlings!
Is this your first time?
Is this your first time? Don't worry, Rustlings was made for beginners! We are
going to teach you a lot of things about Rust, but before we can get
started, here's a couple of notes about how Rustlings operates:
Let's make sure you're up to speed:
- You have Rust installed, preferably via `rustup`
- You have `~/.cargo/bin` added to your PATH variable
- You have cloned this repository (https://github.com/rust-lang/rustlings)
- You have installed Rust language support for your editor
- You have locally installed the `rustlings` command by running an
installation script or manually executing:
1. The central concept behind Rustlings is that you solve exercises. These
exercises usually have some sort of syntax error in them, which will cause
them to fail compilation or testing. Sometimes there's a logic error instead
of a syntax error. No matter what error, it's your job to find it and fix it!
You'll know when you fixed it because then, the exercise will compile and
Rustlings will be able to move on to the next exercise.
2. If you run Rustlings in watch mode (which we recommend), it'll automatically
start with the first exercise. Don't get confused by an error message popping
up as soon as you run Rustlings! This is part of the exercise that you're
supposed to solve, so open the exercise file in an editor and start your
detective work!
3. If you're stuck on an exercise, there is a helpful hint you can view by typing
'hint' (in watch mode), or running `rustlings hint myexercise`.
4. If an exercise doesn't make sense to you, feel free to open an issue on GitHub!
(https://github.com/rust-lang/rustlings/issues/new). We look at every issue,
and sometimes, other learners do too so you can help each other out!
cargo install --force --path .
If you've done all of this (or even most of it), congrats! You're ready
to start working with Rust.
To get started, run `rustlings watch` in order to get the first exercise.
Make sure to have your editor open!
Got all that? Great! To get started, run `rustlings watch` in order to get the first
exercise. Make sure to have your editor open!

24
exercises/README.md Normal file
View file

@ -0,0 +1,24 @@
# Exercise to Book Chapter mapping
| Exercise | Book Chapter |
|------------------------|--------------|
| variables | §3.1 |
| functions | §3.3 |
| if | §3.5 |
| move_semantics | §4.1 |
| primitive_types | §4.3 |
| structs | §5.1 |
| enums | §6 |
| modules | §7.2 |
| collections | §8.1 |
| strings | §8.2 |
| error_handling | §9 |
| generics | §10 |
| option | §10.1 |
| traits | §10.2 |
| tests | §11.1 |
| standard_library_types | §13.2 |
| threads | §16.1 |
| macros | §19.6 |
| clippy | n/a |
| conversions | n/a |

View file

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

View file

@ -0,0 +1,22 @@
# Collections
Rusts standard library includes a number of very useful data
structures called collections. Most other data types represent one
specific value, but collections can contain multiple values. Unlike
the built-in array and tuple types, the data these collections point
to is stored on the heap, which means the amount of data does not need
to be known at compile time and can grow or shrink as the program
runs.
This exercise will get you familiar with two fundamental data
structures that are used very often in Rust programs:
* A *vector* allows you to store a variable number of values next to
each other.
* A *hash map* allows you to associate a value with a particular key.
You may also know this by the names [*unordered map* in C++](https://en.cppreference.com/w/cpp/container/unordered_map),
[*dictionary* in Python](https://docs.python.org/3/tutorial/datastructures.html#dictionaries) or an *associative array* in other languages.
## Further information
- [Storing Lists of Values with Vectors](https://doc.rust-lang.org/stable/book/ch08-01-vectors.html)

View file

@ -0,0 +1,44 @@
// hashmap1.rs
// A basket of fruits in the form of a hash map needs to be defined.
// The key represents the name of the fruit and the value represents
// how many of that particular fruit is in the basket. You have to put
// at least three different types of fruits (e.g apple, banana, mango)
// in the basket and the total count of all the fruits should be at
// least five.
//
// Make me compile and pass the tests!
//
// Execute the command `rustlings hint hashmap1` if you need
// hints.
use std::collections::HashMap;
fn fruit_basket() -> HashMap<String, u32> {
let mut basket = HashMap::new(); // TODO: declare your hash map here.
// Two bananas are already given for you :)
basket.insert(String::from("banana"), 2);
// 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
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn at_least_three_types_of_fruits() {
let basket = fruit_basket();
assert!(basket.len() >= 3);
}
#[test]
fn at_least_five_fruits() {
let basket = fruit_basket();
assert!(basket.values().sum::<u32>() >= 5);
}
}

View file

@ -0,0 +1,79 @@
// hashmap2.rs
// A basket of fruits in the form of a hash map is given. The key
// represents the name of the fruit and the value represents how many
// of that particular fruit is in the basket. You have to put *MORE
// THAN 11* fruits in the basket. Three types of fruits - Apple (4),
// Mango (2) and Lychee (5) are already given in the basket. You are
// not allowed to insert any more of these fruits!
//
// Make me pass the tests!
//
// Execute the command `rustlings hint hashmap2` if you need
// hints.
use std::collections::HashMap;
#[derive(Hash, PartialEq, Eq)]
enum Fruit {
Apple,
Banana,
Mango,
Lychee,
Pineapple,
}
fn fruit_basket(basket: &mut HashMap<Fruit, u32>) {
let fruit_kinds = vec![
Fruit::Apple,
Fruit::Banana,
Fruit::Mango,
Fruit::Lychee,
Fruit::Pineapple,
];
for fruit in fruit_kinds {
if fruit == Fruit::Banana || fruit == Fruit::Pineapple {
basket.insert(fruit, 4);
}
}
}
#[cfg(test)]
mod tests {
use super::*;
fn get_fruit_basket() -> HashMap<Fruit, u32> {
let mut basket = HashMap::<Fruit, u32>::new();
basket.insert(Fruit::Apple, 4);
basket.insert(Fruit::Mango, 2);
basket.insert(Fruit::Lychee, 5);
basket
}
#[test]
fn test_given_fruits_are_not_modified() {
let mut basket = get_fruit_basket();
fruit_basket(&mut basket);
assert_eq!(*basket.get(&Fruit::Apple).unwrap(), 4);
assert_eq!(*basket.get(&Fruit::Mango).unwrap(), 2);
assert_eq!(*basket.get(&Fruit::Lychee).unwrap(), 5);
}
#[test]
fn at_least_five_types_of_fruits() {
let mut basket = get_fruit_basket();
fruit_basket(&mut basket);
let count_fruit_kinds = basket.len();
assert!(count_fruit_kinds >= 5);
}
#[test]
fn greater_than_eleven_fruits() {
let mut basket = get_fruit_basket();
fruit_basket(&mut basket);
let count = basket.values().sum::<u32>();
assert!(count > 11);
}
}

View file

@ -0,0 +1,23 @@
// vec1.rs
// Your task is to create a `Vec` which holds the exact same elements
// as in the array `a`.
// Make me compile and pass the test!
// Execute the command `rustlings hint vec1` if you need hints.
fn array_and_vec() -> ([i32; 4], Vec<i32>) {
let a = [10, 20, 30, 40]; // a plain array
let v = vec![10,20,30,40]; // TODO: declare your vector here with the macro for vectors
(a, v)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_array_and_vec_similarity() {
let (a, v) = array_and_vec();
assert_eq!(a, v[..]);
}
}

View file

@ -0,0 +1,35 @@
// vec2.rs
// A Vec of even numbers is given. Your task is to complete the loop
// so that each number in the Vec is multiplied by 2.
//
// Make me pass the test!
//
// Execute the command `rustlings hint vec2` if you need
// hints.
fn vec_loop(mut v: Vec<i32>) -> Vec<i32> {
for i in v.iter_mut() {
// TODO: Fill this up so that each element in the Vec `v` is
// 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].
v
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_vec_loop() {
let v: Vec<i32> = (1..).filter(|x| x % 2 == 0).take(5).collect();
let ans = vec_loop(v.clone());
assert_eq!(ans, v.iter().map(|x| x * 2).collect::<Vec<i32>>());
}
}

View file

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

View file

@ -115,4 +115,18 @@ mod tests {
assert_eq!(p.name, "John");
assert_eq!(p.age, 30);
}
#[test]
fn test_trailing_comma() {
let p: Person = Person::from("Mike,32,");
assert_eq!(p.name, "John");
assert_eq!(p.age, 30);
}
#[test]
fn test_trailing_comma_and_some_string() {
let p: Person = Person::from("Mike,32,man");
assert_eq!(p.name, "John");
assert_eq!(p.age, 30);
}
}

View file

@ -2,6 +2,7 @@
// Additionally, upon implementing FromStr, you can use the `parse` method
// on strings to generate an object of the implementor type.
// You can read more about it at https://doc.rust-lang.org/std/str/trait.FromStr.html
use std::error;
use std::str::FromStr;
#[derive(Debug)]
@ -11,17 +12,19 @@ struct Person {
}
// I AM NOT DONE
// Steps:
// 1. If the length of the provided string is 0, then return an error
// 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
// 3. Extract the first element from the split operation and use it as the name
// 4. If the name is empty, then 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
// 5. Extract the other element from the split operation and parse it into a `usize` as the age
// with something like `"4".parse::<usize>()`.
// If while parsing the age, something goes wrong, then return an error
// Otherwise, then return a Result of a Person object
// with something like `"4".parse::<usize>()`
// 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
impl FromStr for Person {
type Err = String;
type Err = Box<dyn error::Error>;
fn from_str(s: &str) -> Result<Person, Self::Err> {
}
}
@ -48,38 +51,42 @@ mod tests {
assert_eq!(p.age, 32);
}
#[test]
#[should_panic]
fn missing_age() {
"John,".parse::<Person>().unwrap();
assert!("John,".parse::<Person>().is_err());
}
#[test]
#[should_panic]
fn invalid_age() {
"John,twenty".parse::<Person>().unwrap();
assert!("John,twenty".parse::<Person>().is_err());
}
#[test]
#[should_panic]
fn missing_comma_and_age() {
"John".parse::<Person>().unwrap();
assert!("John".parse::<Person>().is_err());
}
#[test]
#[should_panic]
fn missing_name() {
",1".parse::<Person>().unwrap();
assert!(",1".parse::<Person>().is_err());
}
#[test]
#[should_panic]
fn missing_name_and_age() {
",".parse::<Person>().unwrap();
assert!(",".parse::<Person>().is_err());
}
#[test]
#[should_panic]
fn missing_name_and_invalid_age() {
",one".parse::<Person>().unwrap();
assert!(",one".parse::<Person>().is_err());
}
#[test]
fn trailing_comma() {
assert!("John,32,".parse::<Person>().is_err());
}
#[test]
fn trailing_comma_and_some_string() {
assert!("John,32,man".parse::<Person>().is_err());
}
}

View file

@ -3,8 +3,9 @@
// instead of the target type itself.
// You can read more about it at https://doc.rust-lang.org/std/convert/trait.TryFrom.html
use std::convert::{TryFrom, TryInto};
use std::error;
#[derive(Debug)]
#[derive(Debug, PartialEq)]
struct Color {
red: u8,
green: u8,
@ -15,32 +16,29 @@ struct Color {
// Your task is to complete this implementation
// and return an Ok result of inner type Color.
// You need create implementation for a tuple of three integer,
// an array of three integer and slice of integer.
// You need to create an implementation for a tuple of three integers,
// an array of three integers and a slice of integers.
//
// Note, that implementation for tuple and array will be checked at compile-time,
// but slice implementation need check slice length!
// Also note, that chunk of correct rgb color must be integer in range 0..=255.
// Note that the implementation for tuple and array will be checked at compile time,
// but the slice implementation needs to check the slice length!
// Also note that correct RGB color values must be integers in the 0..=255 range.
// Tuple implementation
impl TryFrom<(i16, i16, i16)> for Color {
type Error = String;
fn try_from(tuple: (i16, i16, i16)) -> Result<Self, Self::Error> {
}
type Error = Box<dyn error::Error>;
fn try_from(tuple: (i16, i16, i16)) -> Result<Self, Self::Error> {}
}
// Array implementation
impl TryFrom<[i16; 3]> for Color {
type Error = String;
fn try_from(arr: [i16; 3]) -> Result<Self, Self::Error> {
}
type Error = Box<dyn error::Error>;
fn try_from(arr: [i16; 3]) -> Result<Self, Self::Error> {}
}
// Slice implementation
impl TryFrom<&[i16]> for Color {
type Error = String;
fn try_from(slice: &[i16]) -> Result<Self, Self::Error> {
}
type Error = Box<dyn error::Error>;
fn try_from(slice: &[i16]) -> Result<Self, Self::Error> {}
}
fn main() {
@ -66,71 +64,95 @@ mod tests {
use super::*;
#[test]
#[should_panic]
fn test_tuple_out_of_range_positive() {
let _ = Color::try_from((256, 1000, 10000)).unwrap();
assert!(Color::try_from((256, 1000, 10000)).is_err());
}
#[test]
#[should_panic]
fn test_tuple_out_of_range_negative() {
let _ = Color::try_from((-1, -10, -256)).unwrap();
assert!(Color::try_from((-1, -10, -256)).is_err());
}
#[test]
fn test_tuple_sum() {
assert!(Color::try_from((-1, 255, 255)).is_err());
}
#[test]
fn test_tuple_correct() {
let c: Color = (183, 65, 14).try_into().unwrap();
assert_eq!(c.red, 183);
assert_eq!(c.green, 65);
assert_eq!(c.blue, 14);
let c: Result<Color, _> = (183, 65, 14).try_into();
assert!(c.is_ok());
assert_eq!(
c.unwrap(),
Color {
red: 183,
green: 65,
blue: 14
}
);
}
#[test]
#[should_panic]
fn test_array_out_of_range_positive() {
let _: Color = [1000, 10000, 256].try_into().unwrap();
let c: Result<Color, _> = [1000, 10000, 256].try_into();
assert!(c.is_err());
}
#[test]
#[should_panic]
fn test_array_out_of_range_negative() {
let _: Color = [-10, -256, -1].try_into().unwrap();
let c: Result<Color, _> = [-10, -256, -1].try_into();
assert!(c.is_err());
}
#[test]
fn test_array_sum() {
let c: Result<Color, _> = [-1, 255, 255].try_into();
assert!(c.is_err());
}
#[test]
fn test_array_correct() {
let c: Color = [183, 65, 14].try_into().unwrap();
assert_eq!(c.red, 183);
assert_eq!(c.green, 65);
assert_eq!(c.blue, 14);
let c: Result<Color, _> = [183, 65, 14].try_into();
assert!(c.is_ok());
assert_eq!(
c.unwrap(),
Color {
red: 183,
green: 65,
blue: 14
}
);
}
#[test]
#[should_panic]
fn test_slice_out_of_range_positive() {
let arr = [10000, 256, 1000];
let _ = Color::try_from(&arr[..]).unwrap();
assert!(Color::try_from(&arr[..]).is_err());
}
#[test]
#[should_panic]
fn test_slice_out_of_range_negative() {
let arr = [-256, -1, -10];
let _ = Color::try_from(&arr[..]).unwrap();
assert!(Color::try_from(&arr[..]).is_err());
}
#[test]
fn test_slice_sum() {
let arr = [-1, 255, 255];
assert!(Color::try_from(&arr[..]).is_err());
}
#[test]
fn test_slice_correct() {
let v = vec![183, 65, 14];
let c = Color::try_from(&v[..]).unwrap();
assert_eq!(c.red, 183);
assert_eq!(c.green, 65);
assert_eq!(c.blue, 14);
let c: Result<Color, _> = Color::try_from(&v[..]);
assert!(c.is_ok());
assert_eq!(
c.unwrap(),
Color {
red: 183,
green: 65,
blue: 14
}
);
}
#[test]
#[should_panic]
fn test_slice_excess_length() {
let v = vec![0, 0, 0, 0];
let _ = Color::try_from(&v[..]).unwrap();
assert!(Color::try_from(&v[..]).is_err());
}
#[test]
#[should_panic]
fn test_slice_insufficient_length() {
let v = vec![0, 0];
let _ = Color::try_from(&v[..]).unwrap();
assert!(Color::try_from(&v[..]).is_err());
}
}

View file

@ -1,10 +1,10 @@
### Enums
# Enums
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. Rusts 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.
#### Book Sections
## Further information
- [Enums](https://doc.rust-lang.org/book/ch06-00-enums.html)
- [Pattern syntax](https://doc.rust-lang.org/book/ch18-03-pattern-syntax.html)

View file

@ -1,11 +1,12 @@
// enums1.rs
// Make me compile! Execute `rustlings hint enums1` for hints!
// I AM NOT DONE
#[derive(Debug)]
enum Message {
// TODO: define a few types of messages as used below
Quit,
Echo,
Move,
ChangeColor
}
fn main() {

View file

@ -1,11 +1,12 @@
// enums2.rs
// Make me compile! Execute `rustlings hint enums2` for hints!
// I AM NOT DONE
#[derive(Debug)]
enum Message {
// TODO: define the different variants used below
Move { x: i32, y: i32 },
Echo(String),
ChangeColor(i32,i32,i32),
Quit
}
impl Message {

View file

@ -1,10 +1,11 @@
// enums3.rs
// Address all the TODOs to make the tests pass!
// I AM NOT DONE
enum Message {
// TODO: implement the message variant types based on their usage below
Move(Point),
Echo(String),
ChangeColor((u8,u8,u8)),
Quit
}
struct Point {
@ -37,6 +38,13 @@ impl State {
fn process(&mut self, message: Message) {
// 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:"),
}
}
}

View file

@ -1,5 +1,11 @@
For this exercise check out the sections:
# Error handling
Most errors arent serious enough to require the program to stop entirely.
Sometimes, when a function fails, its 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 doesnt 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)
- [Generics](https://doc.rust-lang.org/book/ch10-01-syntax.html)
of the Rust Book.
- [Result](https://doc.rust-lang.org/rust-by-example/error/result.html)
- [Boxing errors](https://doc.rust-lang.org/rust-by-example/error/multiple_error_types/boxing_errors.html)

View file

@ -6,14 +6,12 @@
// this function to have.
// Execute `rustlings hint errors1` for hints!
// I AM NOT DONE
pub fn generate_nametag_text(name: String) -> Option<String> {
pub fn generate_nametag_text(name: String) -> Result<String, String> {
if name.len() > 0 {
Some(format!("Hi! My name is {}", name))
Ok(format!("Hi! My name is {}", name))
} else {
// 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() {
assert_eq!(
generate_nametag_text("Beyoncé".into()),
Some("Hi! My name is Beyoncé".into())
Ok("Hi! My name is Beyoncé".into())
);
}
#[test]
#[should_panic]
fn explains_why_generating_nametag_text_fails() {
assert_eq!(
generate_nametag_text("".into()),

View file

@ -16,14 +16,12 @@
// 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.
// I AM NOT DONE
use std::num::ParseIntError;
pub fn total_cost(item_quantity: &str) -> Result<i32, ParseIntError> {
let processing_fee = 1;
let cost_per_item = 5;
let qty = item_quantity.parse::<i32>();
let qty = item_quantity.parse::<i32>()?;
Ok(qty * cost_per_item + processing_fee)
}

View file

@ -4,11 +4,12 @@
// Why not? What should we do to fix it?
// Execute `rustlings hint errors3` for hints!
// I AM NOT DONE
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 pretend_user_input = "8";
@ -20,6 +21,8 @@ fn main() {
tokens -= cost;
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> {

View file

@ -17,19 +17,17 @@
//
// Execute `rustlings hint errorsn` for hints :)
// I AM NOT DONE
use std::error;
use std::fmt;
use std::io;
// 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();
b.read_line(&mut line);
let num: i64 = line.trim().parse();
let answer = PositiveNonzeroInteger::new(num);
answer
b.read_line(&mut line)?;
let num: i64 = line.trim().parse()?;
let answer = PositiveNonzeroInteger::new(num)?;
Ok(answer)
}
//

View file

@ -1,7 +1,7 @@
### Functions
# Functions
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)

View file

@ -1,8 +1,9 @@
// functions1.rs
// Make me compile! Execute `rustlings hint functions1` for hints :)
// I AM NOT DONE
fn main() {
call_me();
}
fn call_me() {
println!("Called!");
}

View file

@ -1,13 +1,11 @@
// functions2.rs
// Make me compile! Execute `rustlings hint functions2` for hints :)
// I AM NOT DONE
fn main() {
call_me(3);
call_me(7);
}
fn call_me(num) {
fn call_me(num:i32) {
for i in 0..num {
println!("Ring! Call number {}", i + 1);
}

View file

@ -1,13 +1,11 @@
// functions3.rs
// Make me compile! Execute `rustlings hint functions3` for hints :)
// I AM NOT DONE
fn main() {
call_me();
call_me(6);
}
fn call_me(num: i32) {
fn call_me(num: u32) {
for i in 0..num {
println!("Ring! Call number {}", i + 1);
}

View file

@ -4,14 +4,12 @@
// 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.
// I AM NOT DONE
fn main() {
let original_price = 51;
println!("Your sale price is {}", sale_price(original_price));
}
fn sale_price(price: i32) -> {
fn sale_price(price: i32) -> i32 {
if is_even(price) {
price - 10
} else {

View file

@ -1,13 +1,17 @@
// functions5.rs
// Make me compile! Execute `rustlings hint functions5` for hints :)
// I AM NOT DONE
fn main() {
let answer = square(3);
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 {
num * num;
num * num
}

View file

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

View file

@ -1,9 +1,7 @@
// This shopping list program isn't compiling!
// Use your knowledge of generics to fix it.
// I AM NOT DONE
fn main() {
let mut shopping_list: Vec<?> = Vec::new();
let mut shopping_list: Vec<&str> = Vec::new();
shopping_list.push("milk");
}

View file

@ -1,14 +1,12 @@
// This powerful wrapper provides the ability to store a positive integer value.
// Rewrite it using generics so that it supports wrapping ANY type.
// I AM NOT DONE
struct Wrapper {
value: u32,
struct Wrapper<T> {
value: T,
}
impl Wrapper {
pub fn new(value: u32) -> Self {
// <T> must be both for impl and Wrapper
impl<T> Wrapper<T> {
pub fn new(value: T) -> Self {
Wrapper { value }
}
}

View file

@ -10,15 +10,15 @@
// Execute 'rustlings hint generics3' for hints!
// I AM NOT DONE
pub struct ReportCard {
pub grade: f32,
pub struct ReportCard<T> {
pub grade: T,
pub student_name: String,
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 {
format!("{} ({}) - achieved a grade of {}",
&self.student_name, &self.student_age, &self.grade)
@ -46,7 +46,7 @@ mod tests {
fn generate_alphabetic_report_card() {
// TODO: Make sure to change the grade here after you finish the exercise.
let report_card = ReportCard {
grade: 2.1,
grade: "A+".to_string(),
student_name: "Gary Plotter".to_string(),
student_age: 11,
};

View file

@ -1,7 +1,7 @@
### If
# If
`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)

View file

@ -1,13 +1,16 @@
// if1.rs
// I AM NOT DONE
pub fn bigger(a: i32, b: i32) -> i32 {
// Complete this function to return the bigger number!
// Do not use:
// - another function call
// - additional variables
// 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 :)

View file

@ -4,13 +4,14 @@
// Step 2: Get the bar_for_fuzz and default_to_baz tests passing!
// Execute the command `rustlings hint if2` if you want a hint :)
// I AM NOT DONE
pub fn fizz_if_foo(fizzish: &str) -> &str {
if fizzish == "fizz" {
"foo"
} else if fizzish == "fuzz" {
"bar"
} else {
1
"baz"
}
}

View file

@ -1,10 +1,10 @@
### Macros
# Macros
Rust's macro system is very powerful, but also kind of difficult to wrap your
head around. We're not going to teach you how to write your own fully-featured
macros. Instead, we'll show you how to use and create them.
#### Book Sections
## Further information
- [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)

View file

@ -1,7 +1,7 @@
### Modules
# Modules
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)

View file

@ -1,10 +1,12 @@
// modules1.rs
// 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 {
fn make_sausage() {
pub fn make_sausage() {
println!("sausage!");
}
}

View file

@ -1,11 +1,9 @@
// modules2.rs
// Make me compile! Execute `rustlings hint modules2` for hints :)
// I AM NOT DONE
mod delicious_snacks {
use self::fruits::PEAR as fruit;
use self::veggies::CUCUMBER as veggie;
pub use self::fruits::PEAR as fruit;
pub use self::veggies::CUCUMBER as veggie;
mod fruits {
pub const PEAR: &'static str = "Pear";

View file

@ -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!!!
#### Book Sections
## Further information
For this section, the book links are especially important.

View file

@ -1,12 +1,11 @@
// move_semantics1.rs
// Make me compile! Execute `rustlings hint move_semantics1` for hints :)
// I AM NOT DONE
fn main() {
let vec0 = Vec::new();
let vec1 = fill_vec(vec0);
let mut vec1 = fill_vec(vec0);
println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);

View file

@ -2,12 +2,10 @@
// Make me compile without changing line 13!
// Execute `rustlings hint move_semantics2` for hints :)
// I AM NOT DONE
fn main() {
let vec0 = Vec::new();
let mut vec1 = fill_vec(vec0);
let mut vec1 = fill_vec(&vec0);
// Do not change the following line!
println!("{} has length {} content `{:?}`", "vec0", vec0.len(), vec0);
@ -17,8 +15,8 @@ fn main() {
println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
}
fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
let mut vec = vec;
fn fill_vec(vec: &[i32]) -> Vec<i32> {
let mut vec = vec.to_vec();
vec.push(22);
vec.push(44);

View file

@ -3,12 +3,10 @@
// (no lines with multiple semicolons necessary!)
// Execute `rustlings hint move_semantics3` for hints :)
// I AM NOT DONE
fn main() {
let vec0 = Vec::new();
let mut vec1 = fill_vec(vec0);
let mut vec1 = fill_vec(&vec0);
println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
@ -17,7 +15,8 @@ fn main() {
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(44);
vec.push(66);

View file

@ -1,15 +1,14 @@
// move_semantics4.rs
// 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.
// Execute `rustlings hint move_semantics4` for hints!
// I AM NOT DONE
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);
@ -18,9 +17,9 @@ fn main() {
println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
}
// `fill_vec()` no longer take `vec: Vec<i32>` as argument
// `fill_vec()` no longer takes `vec: Vec<i32>` as argument
fn fill_vec() -> Vec<i32> {
let mut vec = vec;
let mut vec = Vec::new();
vec.push(22);
vec.push(44);

View file

@ -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 Module Documentation](https://doc.rust-lang.org/std/option/)

View file

@ -9,15 +9,16 @@ fn print_number(maybe_number: Option<u16>) {
}
fn main() {
print_number(13);
print_number(99);
// rustc suggested solutions
print_number(Some(13));
print_number(Some(99));
let mut numbers: [Option<u16>; 5];
let numbers: [Option<u16>; 5];
for iter in 0..5 {
let number_to_add: u16 = {
((iter * 1235) + 2) / (4 * 16)
};
numbers[iter as usize] = number_to_add;
numbers[iter as usize] = Some(number_to_add);
}
}

View file

@ -4,22 +4,22 @@
// I AM NOT DONE
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
value = optional_value {
println!("the value of optional value is: {}", value);
word = optional_word {
println!("The word is: {}", word);
} 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 {
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>
// You can stack `Option<T>`'s into while let and if let
value = optional_values_vec.pop() {
println!("current value: {}", value);
integer = optional_integers_vec.pop() {
println!("current value: {}", integer);
}
}

View file

@ -1,9 +1,9 @@
### Primitive Types
# Primitive Types
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.
#### Book Sections
## Further information
- [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)

View file

@ -2,8 +2,6 @@
// Fill in the rest of the line that has code missing!
// No hints, there's no tricks, just get used to typing these :)
// I AM NOT DONE
fn main() {
// Booleans (`bool`)
@ -12,7 +10,7 @@ fn main() {
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 {
println!("Good evening!");
}

View file

@ -2,8 +2,6 @@
// Fill in the rest of the line that has code missing!
// No hints, there's no tricks, just get used to typing these :)
// I AM NOT DONE
fn main() {
// Characters (`char`)
@ -16,7 +14,7 @@ fn main() {
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
// from a different language than your own, try an emoji!
if your_character.is_alphabetic() {

View file

@ -2,10 +2,9 @@
// Create an array with at least 100 elements in it where the ??? is.
// Execute `rustlings hint primitive_types3` for hints!
// I AM NOT DONE
fn main() {
let a = ???
let a: [i32; 300] = [0; 300];
if a.len() >= 100 {
println!("Wow, that's a big array!");

View file

@ -2,13 +2,11 @@
// Get a slice out of Array a where the ??? is so that the test passes.
// Execute `rustlings hint primitive_types4` for hints!!
// I AM NOT DONE
#[test]
fn slice_out_of_array() {
let a = [1, 2, 3, 4, 5];
let nice_slice = ???
let nice_slice = &a[1..4];
assert_eq!([2, 3, 4], nice_slice)
}

View file

@ -2,11 +2,9 @@
// Destructure the `cat` tuple so that the println will work.
// Execute `rustlings hint primitive_types5` for hints!
// I AM NOT DONE
fn main() {
let cat = ("Furry McFurson", 3.5);
let /* your pattern here */ = cat;
let (name, age) = cat;
println!("{} is {} years old.", name, age);
}

View file

@ -1,11 +1,13 @@
// primitive_types6.rs
// Use a tuple index to access the second element of `numbers`.
// You can put this right into the `println!` where the ??? is.
// You can put the expression for the second element where ??? is so that the test passes.
// Execute `rustlings hint primitive_types6` for hints!
// I AM NOT DONE
fn main() {
#[test]
fn indexing_tuple() {
let numbers = (1, 2, 3);
println!("The second number is {}", ???);
// Replace below ??? with the tuple indexing syntax.
let second = numbers.1;
assert_eq!(2, second,
"This is not the 2nd number in the tuple!")
}

View file

@ -7,10 +7,16 @@
// 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!
// I AM NOT DONE
// Put your function here!
// fn ..... {
fn calculate_apple_price(amount: i32) -> i32 {
if amount > 40 {
1 * amount
} else {
2 * amount
}
}
// Don't modify this function!
#[test]

View file

@ -7,8 +7,6 @@
// 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!
// I AM NOT DONE
fn string_slice(arg: &str) {
println!("{}", arg);
}
@ -17,14 +15,14 @@ fn string(arg: String) {
}
fn main() {
???("blue");
???("red".to_string());
???(String::from("hi"));
???("rust is fun!".to_owned());
???("nice weather".into());
???(format!("Interpolation {}", "Station"));
???(&String::from("abc")[0..1]);
???(" hello there ".trim());
???("Happy Monday!".to_string().replace("Mon", "Tues"));
???("mY sHiFt KeY iS sTiCkY".to_lowercase());
string_slice("blue");
string("red".to_string());
string(String::from("hi"));
string("rust is fun!".to_owned());
string("nice weather".into());
string(format!("Interpolation {}", "Station"));
string_slice(&String::from("abc")[0..1]);
string_slice(" hello there ".trim());
string("Happy Monday!".to_string().replace("Mon", "Tues"));
string("mY sHiFt KeY iS sTiCkY".to_lowercase());
}

View file

@ -24,6 +24,7 @@ mod tests {
#[test]
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!()
}
}

View file

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

View file

@ -1,7 +1,21 @@
// 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
// TODO comment is and create an initial binding for `child_numbers`
// somewhere. Try not to create any copies of the `numbers` Vec!
// first TODO comment is, and create an initial binding for `child_numbers`
// where the second TODO comment is. Try not to create any copies of the `numbers` Vec!
// Execute `rustlings hint arc1` for hints :)
// I AM NOT DONE
@ -16,6 +30,7 @@ fn main() {
let mut joinhandles = Vec::new();
for offset in 0..8 {
let child_numbers = // TODO
joinhandles.push(thread::spawn(move || {
let mut i = offset;
let mut sum = 0;

View file

@ -1,28 +1,41 @@
// iterators2.rs
// In this module, you'll learn some of unique advantages that iterators can offer.
// Step 1. Complete the `capitalize_first` function to pass the first two cases.
// 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.
// In this exercise, you'll learn some of the unique advantages that iterators
// can offer. Follow the steps to complete the exercise.
// As always, there are hints if you execute `rustlings hint iterators2`!
// I AM NOT DONE
// Step 1.
// Complete the `capitalize_first` function.
// "hello" -> "Hello"
pub fn capitalize_first(input: &str) -> String {
let mut c = input.chars();
match c.next() {
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)]
mod tests {
use super::*;
// Step 1.
// Tests that verify your `capitalize_first` function implementation
#[test]
fn test_success() {
assert_eq!(capitalize_first("hello"), "Hello");
@ -33,18 +46,15 @@ mod tests {
assert_eq!(capitalize_first(""), "");
}
// Step 2.
#[test]
fn test_iterate_string_vec() {
let words = vec!["hello", "world"];
let capitalized_words: Vec<String> = // TODO
assert_eq!(capitalized_words, ["Hello", "World"]);
assert_eq!(capitalize_words_vector(&words), ["Hello", "World"]);
}
#[test]
fn test_iterate_into_string() {
let words = vec!["hello", " ", "world"];
let capitalized_words = // TODO
assert_eq!(capitalized_words, "Hello World");
assert_eq!(capitalize_words_string(&words), "Hello World");
}
}

View file

@ -1,11 +1,10 @@
// iterators3.rs
// This is a bigger exercise than most of the others! You can do it!
// Here is your mission, should you choose to accept it:
// 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
// values for `x` using `division_results`.
// 1. Complete the divide function to get the first four tests to pass.
// 2. Get the remaining tests to pass by completing the result_with_list and
// list_of_results functions.
// Execute `rustlings hint iterators3` to get some hints!
// Have fun :-)
// I AM NOT DONE
@ -21,16 +20,28 @@ pub struct NotDivisibleError {
divisor: i32,
}
// This function should calculate `a` divided by `b` if `a` is
// evenly divisible by b.
// Otherwise, it should return a suitable error.
// Calculate `a` divided by `b` if `a` is evenly divisible by `b`.
// Otherwise, return a suitable error.
pub fn divide(a: i32, b: i32) -> Result<i32, DivisionError> {}
// 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)]
mod tests {
use super::*;
// Tests that verify your `divide` function implementation
#[test]
fn test_success() {
assert_eq!(divide(81, 9), Ok(9));
@ -57,22 +68,16 @@ mod tests {
assert_eq!(divide(0, 81), Ok(0));
}
// Iterator exercises using your `divide` function
/*
#[test]
fn result_with_list() {
let numbers = vec![27, 297, 38502, 81];
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])");
fn test_result_with_list() {
assert_eq!(format!("{:?}", result_with_list()), "Ok([1, 11, 1426, 3])");
}
#[test]
fn list_of_results() {
let numbers = vec![27, 297, 38502, 81];
let division_results = numbers.into_iter().map(|n| divide(n, 27));
let x //... Fill in here!
assert_eq!(format!("{:?}", x), "[Ok(1), Ok(11), Ok(1426), Ok(3)]");
fn test_list_of_results() {
assert_eq!(
format!("{:?}", list_of_results()),
"[Ok(1), Ok(11), Ok(1426), Ok(3)]"
);
}
*/
}

View 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]
}
}

View file

@ -1,9 +1,9 @@
### Strings
# Strings
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
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)

View file

@ -2,13 +2,13 @@
// Make me compile without changing the function signature!
// Execute `rustlings hint strings1` for hints ;)
// I AM NOT DONE
fn main() {
let answer = current_favorite_color();
println!("My current favorite color is {}", answer);
}
fn current_favorite_color() -> String {
"blue"
// .to_string uses fmt trait
// .to_owned works too
"blue".to_owned()
}

View file

@ -2,8 +2,6 @@
// Make me compile without changing the function signature!
// Execute `rustlings hint strings2` for hints :)
// I AM NOT DONE
fn main() {
let word = String::from("green"); // Try not changing this line :)
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"
}

View file

@ -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/rust-by-example/custom_types/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)

View file

@ -1,13 +1,12 @@
// structs1.rs
// Address all the TODOs to make the tests pass!
// I AM NOT DONE
struct ColorClassicStruct {
// TODO: Something goes here
name: String,
hex: String
}
struct ColorTupleStruct(/* TODO: Something goes here */);
struct ColorTupleStruct(String, String);
#[derive(Debug)]
struct UnitStruct;
@ -19,8 +18,10 @@ mod tests {
#[test]
fn classic_c_structs() {
// 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.hex, "#00FF00");
}
@ -28,7 +29,7 @@ mod tests {
#[test]
fn tuple_structs() {
// TODO: Instantiate a tuple struct!
// let green =
let green = ColorTupleStruct("green".to_string(),"#00FF00".to_string());
assert_eq!(green.0, "green");
assert_eq!(green.1, "#00FF00");
@ -37,7 +38,7 @@ mod tests {
#[test]
fn unit_structs() {
// TODO: Instantiate a unit struct!
// let unit_struct =
let unit_struct = UnitStruct;
let message = format!("{:?}s are fun!", unit_struct);
assert_eq!(message, "UnitStructs are fun!");

View file

@ -1,8 +1,6 @@
// structs2.rs
// Address all the TODOs to make the tests pass!
// I AM NOT DONE
#[derive(Debug)]
struct Order {
name: String,
@ -34,7 +32,15 @@ mod tests {
fn your_order() {
let order_template = create_order_template();
// 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.year, order_template.year);
assert_eq!(your_order.made_by_phone, order_template.made_by_phone);

View file

@ -1,9 +1,9 @@
// structs3.rs
// Structs contain more than simply some data, they can also have logic, in this
// exercise we have 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`
// Structs contain data, but can also have logic. In this exercise we have
// 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`
// I AM NOT DONE
#[derive(Debug)]
struct Package {
@ -15,7 +15,7 @@ struct Package {
impl Package {
fn new(sender_country: String, recipient_country: String, weight_in_grams: i32) -> Package {
if weight_in_grams <= 0 {
// Something goes here...
panic!("Weight is in negative value.");
} else {
return Package {
sender_country,
@ -25,12 +25,20 @@ impl Package {
}
}
fn is_international(&self) -> ??? {
// Something goes here...
fn is_international(&self) -> bool {
if self.sender_country != self.recipient_country {
true
} else {
false
}
}
fn get_fees(&self, cents_per_gram: i32) -> ??? {
// Something goes here...
fn get_fees(&self, cents_per_gram: i32) -> i32 {
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());
}
#[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]
fn calculate_transport_fees() {
let sender_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);

View file

@ -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!
#### Book Sections
## Further information
- [Writing Tests](https://doc.rust-lang.org/book/ch11-01-writing-tests.html)

View file

@ -20,7 +20,7 @@ mod tests {
}
#[test]
fn is_false_when_even() {
fn is_false_when_odd() {
assert!();
}
}

View file

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

View file

@ -1,7 +1,8 @@
// threads1.rs
// Make this compile! Execute `rustlings hint threads1` for hints :)
// The idea is the thread spawned on line 21 is completing jobs while the main thread is
// monitoring progress until 10 jobs are completed. If you see 6 lines
// The idea is the thread spawned on line 22 is completing jobs while the main thread is
// monitoring progress until 10 jobs are completed. Because of the difference between the
// spawned threads' sleep time, and the waiting threads sleep time, when you see 6 lines
// of "waiting..." and the program ends without timing out when running,
// you've got it :)

View file

@ -1,4 +1,4 @@
### Traits
# Traits
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.
Some additional common Rust traits include:
+ `Clone` (the `clone` method),
+ `Display` (which allows formatted display via `{}`), and
+ `Debug` (which allows formatted display via `{:?}`).
- `Clone` (the `clone` method)
- `Display` (which allows formatted display via `{}`)
- `Debug` (which allows formatted display via `{:?}`)
Because traits indicate shared behavior between data types, they are useful when writing generics.
#### Book Sections
## Further information
- [Traits](https://doc.rust-lang.org/book/ch10-02-traits.html)

View file

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

View file

@ -6,9 +6,7 @@
// 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.
// I AM NOT DONE
fn main() {
x = 5;
let x = 5;
println!("x has the value {}", x);
}

View file

@ -1,10 +1,9 @@
// variables2.rs
// Make me compile! Execute the command `rustlings hint variables2` if you want a hint :)
// I AM NOT DONE
fn main() {
let x;
let x = 10;
if x == 10 {
println!("Ten!");
} else {

View file

@ -1,10 +1,8 @@
// variables3.rs
// Make me compile! Execute the command `rustlings hint variables3` if you want a hint :)
// I AM NOT DONE
fn main() {
let x = 3;
let mut x = 3;
println!("Number {}", x);
x = 5; // don't change this line
println!("Number {}", x);

View file

@ -1,9 +1,8 @@
// variables4.rs
// Make me compile! Execute the command `rustlings hint variables4` if you want a hint :)
// I AM NOT DONE
fn main() {
let x: i32;
let mut x: i32;
x = 512;
println!("Number {}", x);
}

View file

@ -1,11 +1,9 @@
// variables5.rs
// Make me compile! Execute the command `rustlings hint variables5` if you want a hint :)
// I AM NOT DONE
fn main() {
let number = "T-H-R-E-E";
println!("Spell a Number : {}", number);
number = 3;
let number = 3;
println!("Number plus two is : {}", number + 2);
}

View file

@ -1,9 +1,9 @@
// variables6.rs
// Make me compile! Execute the command `rustlings hint variables6` if you want a hint :)
// I AM NOT DONE
const NUMBER = 3;
// consts have to have strict data type definition
// otherwise they won't work
const NUMBER: i32 = 3;
fn main() {
println!("Number {}", NUMBER);
}

1101
info.toml

File diff suppressed because it is too large Load diff

View file

@ -53,7 +53,7 @@ function vercomp($v1, $v2) {
}
$rustVersion = $(rustc --version).Split(" ")[1]
$minRustVersion = "1.31"
$minRustVersion = "1.39"
if ((vercomp $rustVersion $minRustVersion) -eq 2) {
Write-Host "WARNING: Rust version is too old: $rustVersion - needs at least $minRustVersion"
Write-Host "Please update Rust with 'rustup update'"

View file

@ -87,7 +87,7 @@ function vercomp() {
}
RustVersion=$(rustc --version | cut -d " " -f 2)
MinRustVersion=1.31
MinRustVersion=1.39
vercomp $RustVersion $MinRustVersion
if [ $? -eq 2 ]
then

View file

@ -1,5 +1,6 @@
use regex::Regex;
use serde::Deserialize;
use std::env;
use std::fmt::{self, Display, Formatter};
use std::fs::{self, remove_file, File};
use std::io::Read;
@ -11,14 +12,19 @@ const I_AM_DONE_REGEX: &str = r"(?m)^\s*///?\s*I\s+AM\s+NOT\s+DONE";
const CONTEXT: usize = 2;
const CLIPPY_CARGO_TOML_PATH: &str = "./exercises/clippy/Cargo.toml";
// Get a temporary file name that is hopefully unique to this process
// Get a temporary file name that is hopefully unique
#[inline]
fn temp_file() -> String {
format!("./temp_{}", process::id())
let thread_id: String = format!("{:?}", std::thread::current().id())
.chars()
.filter(|c| c.is_alphanumeric())
.collect();
format!("./temp_{}_{}", process::id(), thread_id)
}
// The mode of the exercise.
#[derive(Deserialize, Copy, Clone)]
#[derive(Deserialize, Copy, Clone, Debug)]
#[serde(rename_all = "lowercase")]
pub enum Mode {
// Indicates that the exercise should be compiled as a binary
@ -36,7 +42,7 @@ pub struct ExerciseList {
// A representation of a rustlings exercise.
// This is deserialized from the accompanying info.toml file
#[derive(Deserialize)]
#[derive(Deserialize, Debug)]
pub struct Exercise {
// Name of the exercise
pub name: String,
@ -121,8 +127,12 @@ name = "{}"
path = "{}.rs""#,
self.name, self.name, self.name
);
fs::write(CLIPPY_CARGO_TOML_PATH, cargo_toml)
.expect("Failed to write 📎 Clippy 📎 Cargo.toml file.");
let cargo_toml_error_msg = if env::var("NO_EMOJI").is_ok() {
"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
// an executable, in addition to running clippy. With a
// compilation failure, this would silently fail. But we expect
@ -227,6 +237,16 @@ path = "{}.rs""#,
State::Pending(context)
}
// Check that the exercise looks to be solved using self.state()
// This is not the best way to check since
// the user can just remove the "I AM NOT DONE" string from the file
// without actually having solved anything.
// The only other way to truly check this would to compile and run
// the exercise; which would be both costly and counterintuitive
pub fn looks_done(&self) -> bool {
self.state() == State::Done
}
}
impl Display for Exercise {

View file

@ -1,13 +1,13 @@
use crate::exercise::{Exercise, ExerciseList};
use crate::run::run;
use crate::verify::verify;
use clap::{crate_version, App, Arg, SubCommand};
use argh::FromArgs;
use console::Emoji;
use notify::DebouncedEvent;
use notify::{RecommendedWatcher, RecursiveMode, Watcher};
use std::ffi::OsStr;
use std::fs;
use std::io;
use std::io::{self, prelude::*};
use std::path::Path;
use std::process::{Command, Stdio};
use std::sync::mpsc::channel;
@ -22,41 +22,91 @@ mod exercise;
mod run;
mod verify;
fn main() {
let matches = App::new("rustlings")
.version(crate_version!())
.author("Olivia Hugger, 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)),
)
.get_matches();
// In sync with crate version
const VERSION: &str = "4.4.0";
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!(r#" welcome to... "#);
println!(r#" _ _ _ "#);
@ -86,62 +136,135 @@ fn main() {
let toml_str = &fs::read_to_string("info.toml").unwrap();
let exercises = toml::from_str::<ExerciseList>(toml_str).unwrap().exercises;
let verbose = matches.is_present("nocapture");
let verbose = args.nocapture;
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);
}
if matches.subcommand_matches("verify").is_some() {
verify(&exercises, verbose).unwrap_or_else(|_| std::process::exit(1));
}
if matches.subcommand_matches("watch").is_some() && watch(&exercises, verbose).is_ok() {
println!(
"{emoji} All exercises completed! {emoji}",
emoji = Emoji("🎉", "")
);
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 command = args.nested.unwrap_or_else(|| {
let text = fs::read_to_string("default_out.txt").unwrap();
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>>>) {
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 {
let mut input = String::new();
match io::stdin().read_line(&mut input) {
@ -162,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<()> {
/* Clears the terminal with an ANSI escape code.
Works in UNIX and newer Windows terminals. */
@ -190,7 +334,13 @@ fn watch(exercises: &[Exercise], verbose: bool) -> notify::Result<()> {
let filepath = b.as_path().canonicalize().unwrap();
let pending_exercises = exercises
.iter()
.skip_while(|e| !filepath.ends_with(&e.path));
.skip_while(|e| !filepath.ends_with(&e.path))
// .filter(|e| filepath.ends_with(&e.path))
.chain(
exercises
.iter()
.filter(|e| !e.looks_done() && !filepath.ends_with(&e.path)),
);
clear_screen();
match verify(pending_exercises, verbose) {
Ok(_) => return Ok(()),

View file

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

View file

@ -1,6 +1,7 @@
use crate::exercise::{CompiledExercise, Exercise, Mode, State};
use console::style;
use indicatif::ProgressBar;
use std::env;
// Verify that the provided container of Exercise objects
// 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,
};
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 {
Mode::Compile => "The code is compiling!",
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!("🎉 🎉 {} 🎉 🎉", success_msg);
if no_emoji {
println!("~*~ {} ~*~", success_msg)
} else {
println!("🎉 🎉 {} 🎉 🎉", success_msg)
}
println!();
if let Some(output) = prompt_output {

View file

@ -9,3 +9,10 @@ name = "pending_test_exercise"
path = "pending_test_exercise.rs"
mode = "test"
hint = """"""
[[exercises]]
name = "finished_exercise"
path = "finished_exercise.rs"
mode = "compile"
hint = """"""

View file

@ -24,7 +24,7 @@ fn fails_when_in_wrong_dir() {
fn verify_all_success() {
Command::cargo_bin("rustlings")
.unwrap()
.arg("v")
.arg("verify")
.current_dir("tests/fixture/success")
.assert()
.success();
@ -34,7 +34,7 @@ fn verify_all_success() {
fn verify_fails_if_some_fails() {
Command::cargo_bin("rustlings")
.unwrap()
.arg("v")
.arg("verify")
.current_dir("tests/fixture/failure")
.assert()
.code(1);
@ -44,7 +44,7 @@ fn verify_fails_if_some_fails() {
fn run_single_compile_success() {
Command::cargo_bin("rustlings")
.unwrap()
.args(&["r", "compSuccess"])
.args(&["run", "compSuccess"])
.current_dir("tests/fixture/success/")
.assert()
.success();
@ -54,7 +54,7 @@ fn run_single_compile_success() {
fn run_single_compile_failure() {
Command::cargo_bin("rustlings")
.unwrap()
.args(&["r", "compFailure"])
.args(&["run", "compFailure"])
.current_dir("tests/fixture/failure/")
.assert()
.code(1);
@ -64,7 +64,7 @@ fn run_single_compile_failure() {
fn run_single_test_success() {
Command::cargo_bin("rustlings")
.unwrap()
.args(&["r", "testSuccess"])
.args(&["run", "testSuccess"])
.current_dir("tests/fixture/success/")
.assert()
.success();
@ -74,7 +74,7 @@ fn run_single_test_success() {
fn run_single_test_failure() {
Command::cargo_bin("rustlings")
.unwrap()
.args(&["r", "testFailure"])
.args(&["run", "testFailure"])
.current_dir("tests/fixture/failure/")
.assert()
.code(1);
@ -84,7 +84,7 @@ fn run_single_test_failure() {
fn run_single_test_not_passed() {
Command::cargo_bin("rustlings")
.unwrap()
.args(&["r", "testNotPassed.rs"])
.args(&["run", "testNotPassed.rs"])
.current_dir("tests/fixture/failure/")
.assert()
.code(1);
@ -94,7 +94,7 @@ fn run_single_test_not_passed() {
fn run_single_test_no_filename() {
Command::cargo_bin("rustlings")
.unwrap()
.arg("r")
.arg("run")
.current_dir("tests/fixture/")
.assert()
.code(1);
@ -104,7 +104,7 @@ fn run_single_test_no_filename() {
fn run_single_test_no_exercise() {
Command::cargo_bin("rustlings")
.unwrap()
.args(&["r", "compNoExercise.rs"])
.args(&["run", "compNoExercise.rs"])
.current_dir("tests/fixture/failure")
.assert()
.code(1);
@ -114,7 +114,7 @@ fn run_single_test_no_exercise() {
fn get_hint_for_single_test() {
Command::cargo_bin("rustlings")
.unwrap()
.args(&["h", "testFailure"])
.args(&["hint", "testFailure"])
.current_dir("tests/fixture/failure")
.assert()
.code(0)
@ -131,10 +131,15 @@ fn all_exercises_require_confirmation() {
file.read_to_string(&mut s).unwrap();
s
};
source.matches("// I AM NOT DONE").next().expect(&format!(
"There should be an `I AM NOT DONE` annotation in {:?}",
path
));
source
.matches("// I AM NOT DONE")
.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() {
Command::cargo_bin("rustlings")
.unwrap()
.args(&["r", "pending_exercise"])
.args(&["run", "pending_exercise"])
.current_dir("tests/fixture/state")
.assert()
.code(0)
@ -153,7 +158,7 @@ fn run_compile_exercise_does_not_prompt() {
fn run_test_exercise_does_not_prompt() {
Command::cargo_bin("rustlings")
.unwrap()
.args(&["r", "pending_test_exercise"])
.args(&["run", "pending_test_exercise"])
.current_dir("tests/fixture/state")
.assert()
.code(0)
@ -164,7 +169,7 @@ fn run_test_exercise_does_not_prompt() {
fn run_single_test_success_with_output() {
Command::cargo_bin("rustlings")
.unwrap()
.args(&["--nocapture", "r", "testSuccess"])
.args(&["--nocapture", "run", "testSuccess"])
.current_dir("tests/fixture/success/")
.assert()
.code(0)
@ -175,9 +180,63 @@ fn run_single_test_success_with_output() {
fn run_single_test_success_without_output() {
Command::cargo_bin("rustlings")
.unwrap()
.args(&["r", "testSuccess"])
.args(&["run", "testSuccess"])
.current_dir("tests/fixture/success/")
.assert()
.code(0)
.stdout(predicates::str::contains("THIS TEST TOO SHALL PAS").not());
}
#[test]
fn run_rustlings_list() {
Command::cargo_bin("rustlings")
.unwrap()
.args(&["list"])
.current_dir("tests/fixture/success")
.assert()
.success();
}
#[test]
fn run_rustlings_list_no_pending() {
Command::cargo_bin("rustlings")
.unwrap()
.args(&["list"])
.current_dir("tests/fixture/success")
.assert()
.success()
.stdout(predicates::str::contains("Pending").not());
}
#[test]
fn run_rustlings_list_both_done_and_pending() {
Command::cargo_bin("rustlings")
.unwrap()
.args(&["list"])
.current_dir("tests/fixture/state")
.assert()
.success()
.stdout(predicates::str::contains("Done").and(predicates::str::contains("Pending")));
}
#[test]
fn run_rustlings_list_without_pending() {
Command::cargo_bin("rustlings")
.unwrap()
.args(&["list", "--solved"])
.current_dir("tests/fixture/state")
.assert()
.success()
.stdout(predicates::str::contains("Pending").not());
}
#[test]
fn run_rustlings_list_without_done() {
Command::cargo_bin("rustlings")
.unwrap()
.args(&["list", "--unsolved"])
.current_dir("tests/fixture/state")
.assert()
.success()
.stdout(predicates::str::contains("Done").not());
}