mirror of
https://github.com/notohh/rustlings.git
synced 2024-11-25 14:57:32 -05:00
Merge branch 'main' into rc-exercise
This commit is contained in:
commit
1c3b003c7c
20 changed files with 329 additions and 42 deletions
|
@ -1371,6 +1371,132 @@
|
||||||
"contributions": [
|
"contributions": [
|
||||||
"content"
|
"content"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "wojexe",
|
||||||
|
"name": "wojexe",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/21208490?v=4",
|
||||||
|
"profile": "https://wojexe.com",
|
||||||
|
"contributions": [
|
||||||
|
"content"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "Tostapunk",
|
||||||
|
"name": "Mattia Schiavon",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/25140297?v=4",
|
||||||
|
"profile": "https://github.com/Tostapunk",
|
||||||
|
"contributions": [
|
||||||
|
"content"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "PrettyWood",
|
||||||
|
"name": "Eric Jolibois",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/18406791?v=4",
|
||||||
|
"profile": "http://toucantoco.com",
|
||||||
|
"contributions": [
|
||||||
|
"content"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "EdwinChang24",
|
||||||
|
"name": "Edwin Chang",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/88263098?v=4",
|
||||||
|
"profile": "http://edwinchang.vercel.app",
|
||||||
|
"contributions": [
|
||||||
|
"content"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "saikatdas0790",
|
||||||
|
"name": "Saikat Das",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/7412443?v=4",
|
||||||
|
"profile": "https://saikat.dev/",
|
||||||
|
"contributions": [
|
||||||
|
"content"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "thatlittleboy",
|
||||||
|
"name": "Jeremy Goh",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/30731072?v=4",
|
||||||
|
"profile": "https://github.com/thatlittleboy",
|
||||||
|
"contributions": [
|
||||||
|
"content"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "Lioness100",
|
||||||
|
"name": "Lioness100",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/65814829?v=4",
|
||||||
|
"profile": "https://github.com/Lioness100",
|
||||||
|
"contributions": [
|
||||||
|
"content"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "tvkn",
|
||||||
|
"name": "Tristan Nicholls",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/79277926?v=4",
|
||||||
|
"profile": "https://github.com/tvkn",
|
||||||
|
"contributions": [
|
||||||
|
"content"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "clairew",
|
||||||
|
"name": "Claire",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/9344258?v=4",
|
||||||
|
"profile": "http://clairewang.net",
|
||||||
|
"contributions": [
|
||||||
|
"content"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "Mouwrice",
|
||||||
|
"name": "Maurice Van Wassenhove",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/56763273?v=4",
|
||||||
|
"profile": "https://github.com/Mouwrice",
|
||||||
|
"contributions": [
|
||||||
|
"content"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "johnmendel",
|
||||||
|
"name": "John Mendelewski",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/77524?v=4",
|
||||||
|
"profile": "http://jmthree.com",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "brianfakhoury",
|
||||||
|
"name": "Brian Fakhoury",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/20828724?v=4",
|
||||||
|
"profile": "http://fakhoury.xyz",
|
||||||
|
"contributions": [
|
||||||
|
"content"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "markusboehme",
|
||||||
|
"name": "Markus Boehme",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/5074759?v=4",
|
||||||
|
"profile": "https://github.com/markusboehme",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "nico-vromans",
|
||||||
|
"name": "Nico Vromans",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/48183857?v=4",
|
||||||
|
"profile": "https://github.com/nico-vromans",
|
||||||
|
"contributions": [
|
||||||
|
"content"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"contributorsPerLine": 8,
|
"contributorsPerLine": 8,
|
||||||
|
|
|
@ -2,6 +2,6 @@ root = true
|
||||||
|
|
||||||
[*.rs]
|
[*.rs]
|
||||||
end_of_line = lf
|
end_of_line = lf
|
||||||
insert_final_newfile = true
|
insert_final_newline = true
|
||||||
indent_style = space
|
indent_style = space
|
||||||
indent_size = 4
|
indent_size = 4
|
||||||
|
|
18
AUTHORS.md
18
AUTHORS.md
|
@ -195,6 +195,24 @@ authors.
|
||||||
<td align="center"><a href="https://jamesabromley.wordpress.com/"><img src="https://avatars.githubusercontent.com/u/2474334?v=4?s=100" width="100px;" alt=""/><br /><sub><b>James Bromley</b></sub></a><br /><a href="#content-jayber" title="Content">🖋</a></td>
|
<td align="center"><a href="https://jamesabromley.wordpress.com/"><img src="https://avatars.githubusercontent.com/u/2474334?v=4?s=100" width="100px;" alt=""/><br /><sub><b>James Bromley</b></sub></a><br /><a href="#content-jayber" title="Content">🖋</a></td>
|
||||||
<td align="center"><a href="https://github.com/swhiteCQC"><img src="https://avatars.githubusercontent.com/u/77438466?v=4?s=100" width="100px;" alt=""/><br /><sub><b>swhiteCQC</b></sub></a><br /><a href="#content-swhiteCQC" title="Content">🖋</a></td>
|
<td align="center"><a href="https://github.com/swhiteCQC"><img src="https://avatars.githubusercontent.com/u/77438466?v=4?s=100" width="100px;" alt=""/><br /><sub><b>swhiteCQC</b></sub></a><br /><a href="#content-swhiteCQC" title="Content">🖋</a></td>
|
||||||
<td align="center"><a href="https://github.com/neilpate"><img src="https://avatars.githubusercontent.com/u/7802334?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Neil Pate</b></sub></a><br /><a href="#content-neilpate" title="Content">🖋</a></td>
|
<td align="center"><a href="https://github.com/neilpate"><img src="https://avatars.githubusercontent.com/u/7802334?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Neil Pate</b></sub></a><br /><a href="#content-neilpate" title="Content">🖋</a></td>
|
||||||
|
<td align="center"><a href="https://wojexe.com"><img src="https://avatars.githubusercontent.com/u/21208490?v=4?s=100" width="100px;" alt=""/><br /><sub><b>wojexe</b></sub></a><br /><a href="#content-wojexe" title="Content">🖋</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/Tostapunk"><img src="https://avatars.githubusercontent.com/u/25140297?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Mattia Schiavon</b></sub></a><br /><a href="#content-Tostapunk" title="Content">🖋</a></td>
|
||||||
|
<td align="center"><a href="http://toucantoco.com"><img src="https://avatars.githubusercontent.com/u/18406791?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Eric Jolibois</b></sub></a><br /><a href="#content-PrettyWood" title="Content">🖋</a></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td align="center"><a href="http://edwinchang.vercel.app"><img src="https://avatars.githubusercontent.com/u/88263098?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Edwin Chang</b></sub></a><br /><a href="#content-EdwinChang24" title="Content">🖋</a></td>
|
||||||
|
<td align="center"><a href="https://saikat.dev/"><img src="https://avatars.githubusercontent.com/u/7412443?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Saikat Das</b></sub></a><br /><a href="#content-saikatdas0790" title="Content">🖋</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/thatlittleboy"><img src="https://avatars.githubusercontent.com/u/30731072?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jeremy Goh</b></sub></a><br /><a href="#content-thatlittleboy" title="Content">🖋</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/Lioness100"><img src="https://avatars.githubusercontent.com/u/65814829?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Lioness100</b></sub></a><br /><a href="#content-Lioness100" title="Content">🖋</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/tvkn"><img src="https://avatars.githubusercontent.com/u/79277926?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Tristan Nicholls</b></sub></a><br /><a href="#content-tvkn" title="Content">🖋</a></td>
|
||||||
|
<td align="center"><a href="http://clairewang.net"><img src="https://avatars.githubusercontent.com/u/9344258?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Claire</b></sub></a><br /><a href="#content-clairew" title="Content">🖋</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/Mouwrice"><img src="https://avatars.githubusercontent.com/u/56763273?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Maurice Van Wassenhove</b></sub></a><br /><a href="#content-Mouwrice" title="Content">🖋</a></td>
|
||||||
|
<td align="center"><a href="http://jmthree.com"><img src="https://avatars.githubusercontent.com/u/77524?v=4?s=100" width="100px;" alt=""/><br /><sub><b>John Mendelewski</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=johnmendel" title="Code">💻</a></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td align="center"><a href="http://fakhoury.xyz"><img src="https://avatars.githubusercontent.com/u/20828724?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Brian Fakhoury</b></sub></a><br /><a href="#content-brianfakhoury" title="Content">🖋</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/markusboehme"><img src="https://avatars.githubusercontent.com/u/5074759?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Markus Boehme</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=markusboehme" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/nico-vromans"><img src="https://avatars.githubusercontent.com/u/48183857?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Nico Vromans</b></sub></a><br /><a href="#content-nico-vromans" title="Content">🖋</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|
73
CHANGELOG.md
73
CHANGELOG.md
|
@ -1,3 +1,76 @@
|
||||||
|
<a name="5.0.0"></a>
|
||||||
|
## 5.0.0 (2022-07-16)
|
||||||
|
|
||||||
|
#### Features
|
||||||
|
|
||||||
|
- Hint comments in exercises now also include a reference to the
|
||||||
|
`hint` watch mode subcommand.
|
||||||
|
- **intro1**: Added more hints to point the user to the source file.
|
||||||
|
- **variables**: Switched variables3 and variables4.
|
||||||
|
- Moved `vec` and `primitive_types` exercises before `move_semantics`.
|
||||||
|
- Renamed `vec` to `vecs` to be more in line with the naming in general.
|
||||||
|
- Split up the `collections` exercises in their own folders.
|
||||||
|
- **vec2**: Added a second part of the function that provides an alternative,
|
||||||
|
immutable way of modifying vec values.
|
||||||
|
- **enums3**: Added a hint.
|
||||||
|
- Moved `strings` before `modules`.
|
||||||
|
- Added a `strings3` exercise to teach modifying strings.
|
||||||
|
- Added a `hashmaps3` exercise for some advanced usage of hashmaps.
|
||||||
|
- Moved the original `quiz2` to be `strings4`, since it only tested strings
|
||||||
|
anyways.
|
||||||
|
- Reworked `quiz2` into a new exercise that tests more chapters.
|
||||||
|
- Renamed `option` to `options`.
|
||||||
|
- **options1**: Rewrote parts of the exercise to remove the weird array
|
||||||
|
iteration stuff.
|
||||||
|
- Moved `generics3` to be `quiz3`.
|
||||||
|
- Moved box/arc exercises behind `iterators`.
|
||||||
|
- **iterators4**: Added a test for factorials of zero.
|
||||||
|
- Split `threads1` between two exercises, the first one focusing more on
|
||||||
|
`JoinHandle`s.
|
||||||
|
- Added a `threads3` exercises that uses `std::sync::mpsc`.
|
||||||
|
- Added a `clippy3` exercises with some more interesting checks.
|
||||||
|
- **as_ref_mut**: Added a section that actually tests `AsMut`.
|
||||||
|
- Added 3 new lifetimes exercises.
|
||||||
|
- Added 3 new traits exercises.
|
||||||
|
|
||||||
|
#### Bug Fixes
|
||||||
|
|
||||||
|
- **variables2**: Made output messages more verbose.
|
||||||
|
- **variables5**: Added a nudging hint about shadowing.
|
||||||
|
- **variables6**: Fixed link to book.
|
||||||
|
- **functions**: Clarified the README wording. Generally cleaned up
|
||||||
|
some hints and added some extra comments.
|
||||||
|
- **if2**: Renamed function name to `foo_if_fizz`.
|
||||||
|
- **move_semantics**: Clarified some hints.
|
||||||
|
- **quiz1**: Renamed the function name to be more verbose.
|
||||||
|
- **structs1**: Use an integer type instead of strings. Renamed "unit structs"
|
||||||
|
to "unit-like structs", as is used in the book.
|
||||||
|
- **structs3**: Added the `panic!` statement in from the beginning.
|
||||||
|
- **errors1**: Use `is_empty()` instead of `len() > 0`
|
||||||
|
- **errors3**: Improved the hint.
|
||||||
|
- **errors5**: Improved exercise instructions and the hint.
|
||||||
|
- **errors6**: Provided the skeleton of one of the functions that's supposed
|
||||||
|
to be implemented.
|
||||||
|
- **iterators3**: Inserted `todo!` into `divide()` to keep a compiler error
|
||||||
|
from happening.
|
||||||
|
- **from_str**: Added a hint comment about string error message conversion with
|
||||||
|
`Box<dyn Error>`.
|
||||||
|
- **try_from_into**: Fixed the function name in comment.
|
||||||
|
|
||||||
|
#### Removed
|
||||||
|
|
||||||
|
- Removed the legacy LSP feature that was using `mod.rs` files.
|
||||||
|
- Removed `quiz4`.
|
||||||
|
- Removed `advanced_errs`. These were the last exercises in the recommended
|
||||||
|
order, and I've always felt like they didn't quite fit in with the mostly
|
||||||
|
simple, book-following style we've had in Rustlings.
|
||||||
|
|
||||||
|
#### Housekeeping
|
||||||
|
|
||||||
|
- Added missing exercises to the book index.
|
||||||
|
- Updated spacing in Cargo.toml.
|
||||||
|
- Added a GitHub actions config so that tests run on every PR/commit.
|
||||||
|
|
||||||
<a name="4.8.0"></a>
|
<a name="4.8.0"></a>
|
||||||
## 4.8.0 (2022-07-01)
|
## 4.8.0 (2022-07-01)
|
||||||
|
|
||||||
|
|
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -459,7 +459,7 @@ checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustlings"
|
name = "rustlings"
|
||||||
version = "4.8.0"
|
version = "5.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"argh",
|
"argh",
|
||||||
"assert_cmd",
|
"assert_cmd",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "rustlings"
|
name = "rustlings"
|
||||||
version = "4.8.0"
|
version = "5.0.0"
|
||||||
authors = ["Liv <mokou@fastmail.com>", "Carol (Nichols || Goulding) <carol.nichols@gmail.com>"]
|
authors = ["Liv <mokou@fastmail.com>", "Carol (Nichols || Goulding) <carol.nichols@gmail.com>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
|
|
|
@ -54,11 +54,11 @@ If you get a permission denied message, you might have to exclude the directory
|
||||||
|
|
||||||
## Manually
|
## Manually
|
||||||
|
|
||||||
Basically: Clone the repository at the latest tag, run `cargo install`.
|
Basically: Clone the repository at the latest tag, run `cargo install --path .`.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# find out the latest version at https://github.com/rust-lang/rustlings/releases/latest (on edit 4.7.1)
|
# find out the latest version at https://github.com/rust-lang/rustlings/releases/latest (on edit 5.0.0)
|
||||||
git clone -b 4.7.1 --depth 1 https://github.com/rust-lang/rustlings
|
git clone -b 5.0.0 --depth 1 https://github.com/rust-lang/rustlings
|
||||||
cd rustlings
|
cd rustlings
|
||||||
cargo install --force --path .
|
cargo install --force --path .
|
||||||
```
|
```
|
||||||
|
|
|
@ -5,20 +5,22 @@
|
||||||
| variables | §3.1 |
|
| variables | §3.1 |
|
||||||
| functions | §3.3 |
|
| functions | §3.3 |
|
||||||
| if | §3.5 |
|
| if | §3.5 |
|
||||||
| move_semantics | §4.1, §4.2 |
|
|
||||||
| primitive_types | §3.2, §4.3 |
|
| primitive_types | §3.2, §4.3 |
|
||||||
|
| vecs | §8.1 |
|
||||||
|
| move_semantics | §4.1, §4.2 |
|
||||||
| structs | §5.1, §5.3 |
|
| structs | §5.1, §5.3 |
|
||||||
| enums | §6, §18.3 |
|
| enums | §6, §18.3 |
|
||||||
| modules | §7 |
|
|
||||||
| collections | §8.1, §8.3 |
|
|
||||||
| strings | §8.2 |
|
| strings | §8.2 |
|
||||||
|
| modules | §7 |
|
||||||
|
| hashmaps | §8.3 |
|
||||||
|
| options | §10.1 |
|
||||||
| error_handling | §9 |
|
| error_handling | §9 |
|
||||||
| generics | §10 |
|
| generics | §10 |
|
||||||
| option | §10.1 |
|
|
||||||
| traits | §10.2 |
|
| traits | §10.2 |
|
||||||
| tests | §11.1 |
|
| tests | §11.1 |
|
||||||
|
| lifetimes | §10.3 |
|
||||||
| standard_library_types | §13.2, §15.1, §16.3 |
|
| standard_library_types | §13.2, §15.1, §16.3 |
|
||||||
| threads | §16.1 |
|
| threads | §16.1, §16.2, §16.3 |
|
||||||
| macros | §19.6 |
|
| macros | §19.6 |
|
||||||
| clippy | n/a |
|
| clippy | n/a |
|
||||||
| conversions | n/a |
|
| conversions | n/a |
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
// This exercise uses some concepts that we won't get to until later in the course, like `Box` and the
|
// This exercise uses some concepts that we won't get to until later in the course, like `Box` and the
|
||||||
// `From` trait. It's not important to understand them in detail right now, but you can read ahead if you like.
|
// `From` trait. It's not important to understand them in detail right now, but you can read ahead if you like.
|
||||||
|
// For now, think of the `Box<dyn ...>` type as an "I want anything that does ???" type, which, given
|
||||||
|
// Rust's usual standards for runtime safety, should strike you as somewhat lenient!
|
||||||
|
|
||||||
// In short, this particular use case for boxes is for when you want to own a value and you care only that it is a
|
// In short, this particular use case for boxes is for when you want to own a value and you care only that it is a
|
||||||
// type which implements a particular trait. To do so, The Box is declared as of type Box<dyn Trait> where Trait is the trait
|
// type which implements a particular trait. To do so, The Box is declared as of type Box<dyn Trait> where Trait is the trait
|
||||||
|
|
|
@ -7,4 +7,4 @@ macros. Instead, we'll show you how to use and create them.
|
||||||
## Further information
|
## Further information
|
||||||
|
|
||||||
- [Macros](https://doc.rust-lang.org/book/ch19-06-macros.html)
|
- [Macros](https://doc.rust-lang.org/book/ch19-06-macros.html)
|
||||||
- [The Little Book of Rust Macros](https://danielkeep.github.io/tlborm/book/index.html)
|
- [The Little Book of Rust Macros](https://veykril.github.io/tlborm/)
|
||||||
|
|
|
@ -3,17 +3,13 @@
|
||||||
|
|
||||||
// I AM NOT DONE
|
// I AM NOT DONE
|
||||||
|
|
||||||
// you can modify anything EXCEPT for this function's signature
|
|
||||||
fn print_number(maybe_number: Option<u16>) {
|
|
||||||
println!("printing: {}", maybe_number.unwrap());
|
|
||||||
}
|
|
||||||
|
|
||||||
// This function returns how much icecream there is left in the fridge.
|
// This function returns how much icecream there is left in the fridge.
|
||||||
// If it's before 10PM, there's 5 pieces left. At 10PM, someone eats them
|
// If it's before 10PM, there's 5 pieces left. At 10PM, someone eats them
|
||||||
// all, so there'll be no more left :(
|
// all, so there'll be no more left :(
|
||||||
// TODO: Return an Option!
|
// TODO: Return an Option!
|
||||||
fn maybe_icecream(time_of_day: u16) -> Option<u16> {
|
fn maybe_icecream(time_of_day: u16) -> Option<u16> {
|
||||||
// We use the 24-hour system here, so 10PM is a value of 22
|
// We use the 24-hour system here, so 10PM is a value of 22
|
||||||
|
// The Option output should gracefully handle cases where time_of_day > 24.
|
||||||
???
|
???
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,15 +19,17 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn check_icecream() {
|
fn check_icecream() {
|
||||||
assert_eq!(maybe_icecream(10), Some(5));
|
assert_eq!(maybe_icecream(9), Some(5));
|
||||||
assert_eq!(maybe_icecream(23), None);
|
assert_eq!(maybe_icecream(10), Some(0));
|
||||||
assert_eq!(maybe_icecream(22), None);
|
assert_eq!(maybe_icecream(23), Some(0));
|
||||||
|
assert_eq!(maybe_icecream(22), Some(0));
|
||||||
|
assert_eq!(maybe_icecream(25), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn raw_value() {
|
fn raw_value() {
|
||||||
// TODO: Fix this test. How do you get at the value contained in the Option?
|
// TODO: Fix this test. How do you get at the value contained in the Option?
|
||||||
let icecreams = maybe_icecream(12);
|
let icecreams = maybe_icecream(12);
|
||||||
assert_eq!(icecreams, 5);
|
assert_eq!(icecreams, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ mod my_module {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
// TODO: What to we have to import to have `transformer` in scope?
|
// TODO: What do we have to import to have `transformer` in scope?
|
||||||
use ???;
|
use ???;
|
||||||
use super::Command;
|
use super::Command;
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
// elements: the value of the current item and the next item. The last item is a value called `Nil`.
|
// elements: the value of the current item and the next item. The last item is a value called `Nil`.
|
||||||
//
|
//
|
||||||
// Step 1: use a `Box` in the enum definition to make the code compile
|
// Step 1: use a `Box` in the enum definition to make the code compile
|
||||||
// Step 2: create both empty and non-empty cons lists by replacing `unimplemented!()`
|
// Step 2: create both empty and non-empty cons lists by replacing `todo!()`
|
||||||
//
|
//
|
||||||
// Note: the tests should not be changed
|
// Note: the tests should not be changed
|
||||||
//
|
//
|
||||||
|
@ -33,11 +33,11 @@ fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_empty_list() -> List {
|
pub fn create_empty_list() -> List {
|
||||||
unimplemented!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_non_empty_list() -> List {
|
pub fn create_non_empty_list() -> List {
|
||||||
unimplemented!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
48
exercises/standard_library_types/cow1.rs
Normal file
48
exercises/standard_library_types/cow1.rs
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
// cow1.rs
|
||||||
|
|
||||||
|
// This exercise explores the Cow, or Clone-On-Write type.
|
||||||
|
// Cow is a clone-on-write smart pointer.
|
||||||
|
// It can enclose and provide immutable access to borrowed data, and clone the data lazily when mutation or ownership is required.
|
||||||
|
// The type is designed to work with general borrowed data via the Borrow trait.
|
||||||
|
|
||||||
|
// I AM NOT DONE
|
||||||
|
|
||||||
|
use std::borrow::Cow;
|
||||||
|
|
||||||
|
fn abs_all<'a, 'b>(input: &'a mut Cow<'b, [i32]>) -> &'a mut Cow<'b, [i32]> {
|
||||||
|
for i in 0..input.len() {
|
||||||
|
let v = input[i];
|
||||||
|
if v < 0 {
|
||||||
|
// Clones into a vector if not already owned.
|
||||||
|
input.to_mut()[i] = -v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
input
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// No clone occurs because `input` doesn't need to be mutated.
|
||||||
|
let slice = [0, 1, 2];
|
||||||
|
let mut input = Cow::from(&slice[..]);
|
||||||
|
match abs_all(&mut input) {
|
||||||
|
Cow::Borrowed(_) => println!("I borrowed the slice!"),
|
||||||
|
_ => panic!("expected borrowed value"),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clone occurs because `input` needs to be mutated.
|
||||||
|
let slice = [-1, 0, 1];
|
||||||
|
let mut input = Cow::from(&slice[..]);
|
||||||
|
match abs_all(&mut input) {
|
||||||
|
Cow::Owned(_) => println!("I modified the slice and now own it!"),
|
||||||
|
_ => panic!("expected owned value"),
|
||||||
|
}
|
||||||
|
|
||||||
|
// No clone occurs because `input` is already owned.
|
||||||
|
let slice = vec![-1, 0, 1];
|
||||||
|
let mut input = Cow::from(slice);
|
||||||
|
match abs_all(&mut input) {
|
||||||
|
// TODO
|
||||||
|
Cow::Borrowed(_) => println!("I own this slice!"),
|
||||||
|
_ => panic!("expected borrowed value"),
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,7 +4,7 @@
|
||||||
// I AM NOT DONE
|
// I AM NOT DONE
|
||||||
|
|
||||||
fn trim_me(input: &str) -> String {
|
fn trim_me(input: &str) -> String {
|
||||||
// TODO: Remove whitespace from the end of a string!
|
// TODO: Remove whitespace from both ends of a string!
|
||||||
???
|
???
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// traits4.rs
|
// traits4.rs
|
||||||
//
|
//
|
||||||
// Your task is to replace the '??' sections so the code compiles.
|
// Your task is to replace the '??' sections so the code compiles.
|
||||||
// Don't change any line other than 21.
|
// Don't change any line other than the marked one.
|
||||||
// Execute `rustlings hint traits4` or use the `hint` watch subcommand for a hint.
|
// Execute `rustlings hint traits4` or use the `hint` watch subcommand for a hint.
|
||||||
|
|
||||||
// I AM NOT DONE
|
// I AM NOT DONE
|
||||||
|
@ -19,6 +19,7 @@ struct OtherSoftware {}
|
||||||
impl Licensed for SomeSoftware {}
|
impl Licensed for SomeSoftware {}
|
||||||
impl Licensed for OtherSoftware {}
|
impl Licensed for OtherSoftware {}
|
||||||
|
|
||||||
|
// YOU MAY ONLY CHANGE THE NEXT LINE
|
||||||
fn compare_license_types(software: ??, software_two: ??) -> bool {
|
fn compare_license_types(software: ??, software_two: ??) -> bool {
|
||||||
software.licensing_info() == software_two.licensing_info()
|
software.licensing_info() == software_two.licensing_info()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// traits5.rs
|
// traits5.rs
|
||||||
//
|
//
|
||||||
// Your task is to replace the '??' sections so the code compiles.
|
// Your task is to replace the '??' sections so the code compiles.
|
||||||
// Don't change any line other than 27.
|
// Don't change any line other than the marked one.
|
||||||
// Execute `rustlings hint traits5` or use the `hint` watch subcommand for a hint.
|
// Execute `rustlings hint traits5` or use the `hint` watch subcommand for a hint.
|
||||||
|
|
||||||
// I AM NOT DONE
|
// I AM NOT DONE
|
||||||
|
@ -18,15 +18,20 @@ pub trait OtherTrait {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SomeStruct {
|
struct SomeStruct {}
|
||||||
name: String,
|
struct OtherStruct {}
|
||||||
}
|
|
||||||
|
|
||||||
impl SomeTrait for SomeStruct {}
|
impl SomeTrait for SomeStruct {}
|
||||||
impl OtherTrait for SomeStruct {}
|
impl OtherTrait for SomeStruct {}
|
||||||
|
impl SomeTrait for OtherStruct {}
|
||||||
|
impl OtherTrait for OtherStruct {}
|
||||||
|
|
||||||
|
// YOU MAY ONLY CHANGE THE NEXT LINE
|
||||||
fn some_func(item: ??) -> bool {
|
fn some_func(item: ??) -> bool {
|
||||||
item.some_function() && item.other_function()
|
item.some_function() && item.other_function()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {
|
||||||
|
some_func(SomeStruct {});
|
||||||
|
some_func(OtherStruct {});
|
||||||
|
}
|
||||||
|
|
28
info.toml
28
info.toml
|
@ -63,7 +63,7 @@ name = "variables5"
|
||||||
path = "exercises/variables/variables5.rs"
|
path = "exercises/variables/variables5.rs"
|
||||||
mode = "compile"
|
mode = "compile"
|
||||||
hint = """
|
hint = """
|
||||||
In variables3 we already learned how to make an immutable variable mutable
|
In variables4 we already learned how to make an immutable variable mutable
|
||||||
using a special keyword. Unfortunately this doesn't help us much in this exercise
|
using a special keyword. Unfortunately this doesn't help us much in this exercise
|
||||||
because we want to assign a different typed value to an existing variable. Sometimes
|
because we want to assign a different typed value to an existing variable. Sometimes
|
||||||
you may also like to reuse existing variable names because you are just converting
|
you may also like to reuse existing variable names because you are just converting
|
||||||
|
@ -123,8 +123,8 @@ name = "functions4"
|
||||||
path = "exercises/functions/functions4.rs"
|
path = "exercises/functions/functions4.rs"
|
||||||
mode = "compile"
|
mode = "compile"
|
||||||
hint = """
|
hint = """
|
||||||
The error message points to line 14 and says it expects a type after the
|
The error message points to line 17 and says it expects a type after the
|
||||||
`->`. This is where the function's return type should be-- take a look at
|
`->`. This is where the function's return type should be -- take a look at
|
||||||
the `is_even` function for an example!
|
the `is_even` function for an example!
|
||||||
|
|
||||||
Also: Did you figure out that, technically, u32 would be the more fitting type
|
Also: Did you figure out that, technically, u32 would be the more fitting type
|
||||||
|
@ -732,7 +732,7 @@ name = "traits5"
|
||||||
path = "exercises/traits/traits5.rs"
|
path = "exercises/traits/traits5.rs"
|
||||||
mode = "compile"
|
mode = "compile"
|
||||||
hint = """
|
hint = """
|
||||||
To ensure a paramter implements multiple traits use the '+ syntax'. Try replacing the
|
To ensure a parameter implements multiple traits use the '+ syntax'. Try replacing the
|
||||||
'??' with 'impl <> + <>'.
|
'??' with 'impl <> + <>'.
|
||||||
|
|
||||||
See the documentation at: https://doc.rust-lang.org/book/ch10-02-traits.html#specifying-multiple-trait-bounds-with-the--syntax
|
See the documentation at: https://doc.rust-lang.org/book/ch10-02-traits.html#specifying-multiple-trait-bounds-with-the--syntax
|
||||||
|
@ -746,7 +746,7 @@ path = "exercises/quiz3.rs"
|
||||||
mode = "test"
|
mode = "test"
|
||||||
hint = """
|
hint = """
|
||||||
To find the best solution to this challenge you're going to need to think back to your
|
To find the best solution to this challenge you're going to need to think back to your
|
||||||
knowledge of traits, specifically Trait Bound Syntax - you may also need this: "use std::fmt::Display;""""
|
knowledge of traits, specifically Trait Bound Syntax - you may also need this: `use std::fmt::Display;`."""
|
||||||
|
|
||||||
# TESTS
|
# TESTS
|
||||||
|
|
||||||
|
@ -795,7 +795,10 @@ name = "lifetimes2"
|
||||||
path = "exercises/lifetimes/lifetimes2.rs"
|
path = "exercises/lifetimes/lifetimes2.rs"
|
||||||
mode = "compile"
|
mode = "compile"
|
||||||
hint = """
|
hint = """
|
||||||
What is the compiler checking? How could you change how long an owned variable lives?"""
|
Remember that the generic lifetime 'a will get the concrete lifetime that is equal to the smaller of the lifetimes of x and y.
|
||||||
|
You can take at least two paths to achieve the desired result while keeping the inner block:
|
||||||
|
1. Move the string2 declaration to make it live as long as string1 (how is result declared?)
|
||||||
|
2. Move println! into the inner block"""
|
||||||
|
|
||||||
[[exercises]]
|
[[exercises]]
|
||||||
name = "lifetimes3"
|
name = "lifetimes3"
|
||||||
|
@ -943,6 +946,17 @@ https://doc.rust-lang.org/book/ch15-04-rc.html
|
||||||
* Unforunately Pluto is no longer considered a planet :(
|
* Unforunately Pluto is no longer considered a planet :(
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
[[exercises]]
|
||||||
|
name = "cow1"
|
||||||
|
path = "exercises/standard_library_types/cow1.rs"
|
||||||
|
mode = "compile"
|
||||||
|
hint = """
|
||||||
|
Since the vector is already owned, the `Cow` type doesn't need to clone it.
|
||||||
|
|
||||||
|
Checkout https://doc.rust-lang.org/std/borrow/enum.Cow.html for documentation
|
||||||
|
on the `Cow` type.
|
||||||
|
"""
|
||||||
|
|
||||||
# THREADS
|
# THREADS
|
||||||
|
|
||||||
[[exercises]]
|
[[exercises]]
|
||||||
|
@ -999,7 +1013,7 @@ An alternate way to handle concurrency between threads is to use
|
||||||
a mpsc (multiple producer, single consumer) channel to communicate.
|
a mpsc (multiple producer, single consumer) channel to communicate.
|
||||||
With both a sending end and a receiving end, it's possible to
|
With both a sending end and a receiving end, it's possible to
|
||||||
send values in one thread and receieve them in another.
|
send values in one thread and receieve them in another.
|
||||||
Multiple producers are possibile by using clone() to create a duplicate
|
Multiple producers are possible by using clone() to create a duplicate
|
||||||
of the original sending end.
|
of the original sending end.
|
||||||
See https://doc.rust-lang.org/book/ch16-02-message-passing.html for more info.
|
See https://doc.rust-lang.org/book/ch16-02-message-passing.html for more info.
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -26,7 +26,7 @@ mod run;
|
||||||
mod verify;
|
mod verify;
|
||||||
|
|
||||||
// In sync with crate version
|
// In sync with crate version
|
||||||
const VERSION: &str = "4.8.0";
|
const VERSION: &str = "5.0.0";
|
||||||
|
|
||||||
#[derive(FromArgs, PartialEq, Debug)]
|
#[derive(FromArgs, PartialEq, Debug)]
|
||||||
/// Rustlings is a collection of small exercises to get you used to writing and reading Rust code
|
/// Rustlings is a collection of small exercises to get you used to writing and reading Rust code
|
||||||
|
|
|
@ -176,7 +176,7 @@ fn run_single_test_success_with_output() {
|
||||||
.current_dir("tests/fixture/success/")
|
.current_dir("tests/fixture/success/")
|
||||||
.assert()
|
.assert()
|
||||||
.code(0)
|
.code(0)
|
||||||
.stdout(predicates::str::contains("THIS TEST TOO SHALL PAS"));
|
.stdout(predicates::str::contains("THIS TEST TOO SHALL PASS"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -187,7 +187,7 @@ fn run_single_test_success_without_output() {
|
||||||
.current_dir("tests/fixture/success/")
|
.current_dir("tests/fixture/success/")
|
||||||
.assert()
|
.assert()
|
||||||
.code(0)
|
.code(0)
|
||||||
.stdout(predicates::str::contains("THIS TEST TOO SHALL PAS").not());
|
.stdout(predicates::str::contains("THIS TEST TOO SHALL PASS").not());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
Loading…
Reference in a new issue