Merge branch 'main' into rc-exercise

This commit is contained in:
liv 2022-08-16 09:37:34 +02:00 committed by GitHub
commit 1c3b003c7c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 329 additions and 42 deletions

View File

@ -1371,6 +1371,132 @@
"contributions": [
"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,

View File

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

View File

@ -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://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://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>
</table>

View File

@ -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>
## 4.8.0 (2022-07-01)

2
Cargo.lock generated
View File

@ -459,7 +459,7 @@ checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
[[package]]
name = "rustlings"
version = "4.8.0"
version = "5.0.0"
dependencies = [
"argh",
"assert_cmd",

View File

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

View File

@ -54,11 +54,11 @@ If you get a permission denied message, you might have to exclude the directory
## 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
# find out the latest version at https://github.com/rust-lang/rustlings/releases/latest (on edit 4.7.1)
git clone -b 4.7.1 --depth 1 https://github.com/rust-lang/rustlings
# find out the latest version at https://github.com/rust-lang/rustlings/releases/latest (on edit 5.0.0)
git clone -b 5.0.0 --depth 1 https://github.com/rust-lang/rustlings
cd rustlings
cargo install --force --path .
```

View File

@ -5,20 +5,22 @@
| variables | §3.1 |
| functions | §3.3 |
| if | §3.5 |
| move_semantics | §4.1, §4.2 |
| primitive_types | §3.2, §4.3 |
| vecs | §8.1 |
| move_semantics | §4.1, §4.2 |
| structs | §5.1, §5.3 |
| enums | §6, §18.3 |
| modules | §7 |
| collections | §8.1, §8.3 |
| strings | §8.2 |
| modules | §7 |
| hashmaps | §8.3 |
| options | §10.1 |
| error_handling | §9 |
| generics | §10 |
| option | §10.1 |
| traits | §10.2 |
| tests | §11.1 |
| lifetimes | §10.3 |
| standard_library_types | §13.2, §15.1, §16.3 |
| threads | §16.1 |
| threads | §16.1, §16.2, §16.3 |
| macros | §19.6 |
| clippy | n/a |
| conversions | n/a |

View File

@ -4,6 +4,8 @@
// This exercise uses some concepts that we won't get to until later in the course, like `Box` and the
// `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
// type which implements a particular trait. To do so, The Box is declared as of type Box<dyn Trait> where Trait is the trait

View File

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

View File

@ -3,17 +3,13 @@
// I AM NOT DONE
// 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.
// If it's before 10PM, there's 5 pieces left. At 10PM, someone eats them
// all, so there'll be no more left :(
// TODO: Return an Option!
fn maybe_icecream(time_of_day: u16) -> Option<u16> {
// 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]
fn check_icecream() {
assert_eq!(maybe_icecream(10), Some(5));
assert_eq!(maybe_icecream(23), None);
assert_eq!(maybe_icecream(22), None);
assert_eq!(maybe_icecream(9), Some(5));
assert_eq!(maybe_icecream(10), Some(0));
assert_eq!(maybe_icecream(23), Some(0));
assert_eq!(maybe_icecream(22), Some(0));
assert_eq!(maybe_icecream(25), None);
}
#[test]
fn raw_value() {
// TODO: Fix this test. How do you get at the value contained in the Option?
let icecreams = maybe_icecream(12);
assert_eq!(icecreams, 5);
assert_eq!(icecreams, 0);
}
}

View File

@ -42,7 +42,7 @@ mod my_module {
#[cfg(test)]
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 super::Command;

View File

@ -10,7 +10,7 @@
// elements: the value of the current item and the next item. The last item is a value called `Nil`.
//
// 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
//
@ -33,11 +33,11 @@ fn main() {
}
pub fn create_empty_list() -> List {
unimplemented!()
todo!()
}
pub fn create_non_empty_list() -> List {
unimplemented!()
todo!()
}
#[cfg(test)]

View File

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

View File

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

View File

@ -1,7 +1,7 @@
// traits4.rs
//
// 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.
// I AM NOT DONE
@ -19,6 +19,7 @@ struct OtherSoftware {}
impl Licensed for SomeSoftware {}
impl Licensed for OtherSoftware {}
// YOU MAY ONLY CHANGE THE NEXT LINE
fn compare_license_types(software: ??, software_two: ??) -> bool {
software.licensing_info() == software_two.licensing_info()
}

View File

@ -1,7 +1,7 @@
// traits5.rs
//
// 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.
// I AM NOT DONE
@ -18,15 +18,20 @@ pub trait OtherTrait {
}
}
struct SomeStruct {
name: String,
}
struct SomeStruct {}
struct OtherStruct {}
impl SomeTrait 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 {
item.some_function() && item.other_function()
}
fn main() {}
fn main() {
some_func(SomeStruct {});
some_func(OtherStruct {});
}

View File

@ -63,7 +63,7 @@ name = "variables5"
path = "exercises/variables/variables5.rs"
mode = "compile"
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
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
@ -123,8 +123,8 @@ name = "functions4"
path = "exercises/functions/functions4.rs"
mode = "compile"
hint = """
The error message points to line 14 and says it expects a type after the
`->`. This is where the function's return type should be-- take a look at
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
the `is_even` function for an example!
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"
mode = "compile"
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 <> + <>'.
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"
hint = """
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
@ -795,7 +795,10 @@ name = "lifetimes2"
path = "exercises/lifetimes/lifetimes2.rs"
mode = "compile"
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]]
name = "lifetimes3"
@ -943,6 +946,17 @@ https://doc.rust-lang.org/book/ch15-04-rc.html
* Unforunately Pluto is no longer considered a planet :(
"""
[[exercises]]
name = "cow1"
path = "exercises/standard_library_types/cow1.rs"
mode = "compile"
hint = """
Since the vector is already owned, the `Cow` type doesn't need to clone it.
Checkout https://doc.rust-lang.org/std/borrow/enum.Cow.html for documentation
on the `Cow` type.
"""
# THREADS
[[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.
With both a sending end and a receiving end, it's possible to
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.
See https://doc.rust-lang.org/book/ch16-02-message-passing.html for more info.
"""

View File

@ -26,7 +26,7 @@ mod run;
mod verify;
// In sync with crate version
const VERSION: &str = "4.8.0";
const VERSION: &str = "5.0.0";
#[derive(FromArgs, PartialEq, Debug)]
/// Rustlings is a collection of small exercises to get you used to writing and reading Rust code

View File

@ -176,7 +176,7 @@ fn run_single_test_success_with_output() {
.current_dir("tests/fixture/success/")
.assert()
.code(0)
.stdout(predicates::str::contains("THIS TEST TOO SHALL PAS"));
.stdout(predicates::str::contains("THIS TEST TOO SHALL PASS"));
}
#[test]
@ -187,7 +187,7 @@ fn run_single_test_success_without_output() {
.current_dir("tests/fixture/success/")
.assert()
.code(0)
.stdout(predicates::str::contains("THIS TEST TOO SHALL PAS").not());
.stdout(predicates::str::contains("THIS TEST TOO SHALL PASS").not());
}
#[test]