mirror of
https://github.com/rust-lang/rustlings.git
synced 2025-12-26 00:11:49 +02:00
Compare commits
56 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7f1754ecc5 | ||
|
|
e4971ec7b3 | ||
|
|
ec974f5dac | ||
|
|
7b2bfda37f | ||
|
|
2f34370f2f | ||
|
|
94799b1e98 | ||
|
|
d334e0c66c | ||
|
|
3da5816db2 | ||
|
|
c8273e06c6 | ||
|
|
ff50159a3d | ||
|
|
34aafa82f9 | ||
|
|
278a1f103b | ||
|
|
1acbbb6d43 | ||
|
|
e3a20b8bc8 | ||
|
|
f7678b4a9e | ||
|
|
52ed5dbcf9 | ||
|
|
6c5ba7cc01 | ||
|
|
36e66b545e | ||
|
|
0e9966d6a4 | ||
|
|
75fbf7a8f3 | ||
|
|
e700a3cc4d | ||
|
|
eb7f21df04 | ||
|
|
ac9c1adb75 | ||
|
|
d06f7bf1ff | ||
|
|
7f06bb5fa7 | ||
|
|
0ad8eec3eb | ||
|
|
3c841c4685 | ||
|
|
d5b647d5ab | ||
|
|
86f8fa8e6e | ||
|
|
351e4e2460 | ||
|
|
1afc7ed8c5 | ||
|
|
fcadbfc70d | ||
|
|
8c88f769b6 | ||
|
|
de24536187 | ||
|
|
701b4bef51 | ||
|
|
045d86aa42 | ||
|
|
bec7be05f5 | ||
|
|
d42ac49de4 | ||
|
|
1272d0b990 | ||
|
|
cf86e734f2 | ||
|
|
238a496af5 | ||
|
|
a3670d267b | ||
|
|
65f05f0541 | ||
|
|
338c95f120 | ||
|
|
2b9dc4424e | ||
|
|
ef0b25c392 | ||
|
|
6f0e5d13ed | ||
|
|
046a18cd16 | ||
|
|
e1e67d0d41 | ||
|
|
216d08d013 | ||
|
|
bbdc5c6039 | ||
|
|
149e0c8ac2 | ||
|
|
48ce9d2fd8 | ||
|
|
b653d4848a | ||
|
|
4972bede48 | ||
|
|
f94f365e14 |
@@ -1839,6 +1839,69 @@
|
||||
"contributions": [
|
||||
"content"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "black-puppydog",
|
||||
"name": "Daan Wynen",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/189241?v=4",
|
||||
"profile": "https://github.com/black-puppydog",
|
||||
"contributions": [
|
||||
"content"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Anush008",
|
||||
"name": "Anush",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/46051506?v=4",
|
||||
"profile": "https://github.com/Anush008",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "shgew",
|
||||
"name": "Gleb Shevchenko",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/5584672?v=4",
|
||||
"profile": "https://github.com/shgew",
|
||||
"contributions": [
|
||||
"content"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "mdmundo",
|
||||
"name": "Edmundo Paulino",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/60408300?v=4",
|
||||
"profile": "https://github.com/mdmundo",
|
||||
"contributions": [
|
||||
"infra"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "eroullit",
|
||||
"name": "Emmanuel Roullit",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/301795?v=4",
|
||||
"profile": "https://github.com/eroullit",
|
||||
"contributions": [
|
||||
"infra"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "nidhalmessaoudi",
|
||||
"name": "Nidhal Messaoudi",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/63377412?v=4",
|
||||
"profile": "https://nidhalmessaoudi.herokuapp.com",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "MahdiBM",
|
||||
"name": "Mahdi Bahrami",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/54685446?v=4",
|
||||
"profile": "https://github.com/MahdiBM",
|
||||
"contributions": [
|
||||
"tool"
|
||||
]
|
||||
}
|
||||
],
|
||||
"contributorsPerLine": 8,
|
||||
|
||||
17
.devcontainer/devcontainer.json
Normal file
17
.devcontainer/devcontainer.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"image": "mcr.microsoft.com/devcontainers/universal:2-linux",
|
||||
"waitFor": "onCreateCommand",
|
||||
"onCreateCommand": ".devcontainer/setup.sh",
|
||||
"updateContentCommand": "cargo build",
|
||||
"postCreateCommand": "",
|
||||
"postAttachCommand": {
|
||||
"server": "rustlings watch"
|
||||
},
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"extensions": [
|
||||
"rust-lang.rust-analyzer"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
7
.devcontainer/setup.sh
Executable file
7
.devcontainer/setup.sh
Executable file
@@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
curl https://sh.rustup.rs -sSf | sh -s -- -y
|
||||
|
||||
# Update current shell environment variables after install to find rustup
|
||||
. "$HOME/.cargo/env"
|
||||
rustup install stable
|
||||
bash install.sh
|
||||
2
.replit
2
.replit
@@ -1,2 +0,0 @@
|
||||
language = "rust"
|
||||
run = "[ -x ~/.cargo/bin/rustlings ] && ~/.cargo/bin/rustlings watch || ./install.sh"
|
||||
@@ -262,6 +262,13 @@ authors.
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="12.5%"><a href="https://grzegorz-zur.com/"><img src="https://avatars.githubusercontent.com/u/5297583?v=4?s=100" width="100px;" alt="Grzegorz Żur"/><br /><sub><b>Grzegorz Żur</b></sub></a><br /><a href="#content-grzegorz-zur" title="Content">🖋</a></td>
|
||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/black-puppydog"><img src="https://avatars.githubusercontent.com/u/189241?v=4?s=100" width="100px;" alt="Daan Wynen"/><br /><sub><b>Daan Wynen</b></sub></a><br /><a href="#content-black-puppydog" title="Content">🖋</a></td>
|
||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/Anush008"><img src="https://avatars.githubusercontent.com/u/46051506?v=4?s=100" width="100px;" alt="Anush"/><br /><sub><b>Anush</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=Anush008" title="Documentation">📖</a></td>
|
||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/shgew"><img src="https://avatars.githubusercontent.com/u/5584672?v=4?s=100" width="100px;" alt="Gleb Shevchenko"/><br /><sub><b>Gleb Shevchenko</b></sub></a><br /><a href="#content-shgew" title="Content">🖋</a></td>
|
||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/mdmundo"><img src="https://avatars.githubusercontent.com/u/60408300?v=4?s=100" width="100px;" alt="Edmundo Paulino"/><br /><sub><b>Edmundo Paulino</b></sub></a><br /><a href="#infra-mdmundo" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a></td>
|
||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/eroullit"><img src="https://avatars.githubusercontent.com/u/301795?v=4?s=100" width="100px;" alt="Emmanuel Roullit"/><br /><sub><b>Emmanuel Roullit</b></sub></a><br /><a href="#infra-eroullit" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a></td>
|
||||
<td align="center" valign="top" width="12.5%"><a href="https://nidhalmessaoudi.herokuapp.com"><img src="https://avatars.githubusercontent.com/u/63377412?v=4?s=100" width="100px;" alt="Nidhal Messaoudi"/><br /><sub><b>Nidhal Messaoudi</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=nidhalmessaoudi" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="12.5%"><a href="https://github.com/MahdiBM"><img src="https://avatars.githubusercontent.com/u/54685446?v=4?s=100" width="100px;" alt="Mahdi Bahrami"/><br /><sub><b>Mahdi Bahrami</b></sub></a><br /><a href="#tool-MahdiBM" title="Tools">🔧</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
16
CHANGELOG.md
16
CHANGELOG.md
@@ -1,3 +1,19 @@
|
||||
<a name="5.4.1"></a>
|
||||
## 5.4.1 (2023-03-10)
|
||||
|
||||
#### Changed
|
||||
|
||||
- `vecs`: Added links to `iter_mut` and `map` to README.md
|
||||
- `cow1`: Changed main to tests
|
||||
- `iterators1`: Formatted according to rustfmt
|
||||
|
||||
#### Fixed
|
||||
|
||||
- `errors5`: Unified undisclosed type notation
|
||||
- `arc1`: Improved readability by avoiding implicit dereference
|
||||
- `macros4`: Prevented auto-fix by adding `#[rustfmt::skip]`
|
||||
- `cli`: Actually show correct progress percentages
|
||||
|
||||
<a name="5.4.0"></a>
|
||||
|
||||
## 5.4.0 (2023-02-12)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "rustlings"
|
||||
version = "5.4.0"
|
||||
version = "5.4.1"
|
||||
authors = [
|
||||
"Liv <mokou@fastmail.com>",
|
||||
"Carol (Nichols || Goulding) <carol.nichols@gmail.com>",
|
||||
|
||||
15
README.md
15
README.md
@@ -33,8 +33,8 @@ This will install Rustlings and give you access to the `rustlings` command. Run
|
||||
Basically: Clone the repository at the latest tag, finally run `nix develop` or `nix-shell`.
|
||||
|
||||
```bash
|
||||
# find out the latest version at https://github.com/rust-lang/rustlings/releases/latest (on edit 5.4.0)
|
||||
git clone -b 5.4.0 --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.4.1)
|
||||
git clone -b 5.4.1 --depth 1 https://github.com/rust-lang/rustlings
|
||||
cd rustlings
|
||||
# if nix version > 2.3
|
||||
nix develop
|
||||
@@ -62,17 +62,17 @@ If you get a permission denied message, you might have to exclude the directory
|
||||
|
||||
## Browser
|
||||
|
||||
[Run on Repl.it](https://repl.it/github/rust-lang/rustlings)
|
||||
|
||||
[](https://gitpod.io/#https://github.com/rust-lang/rustlings)
|
||||
|
||||
[](https://github.com/codespaces/new/?repo=rust-lang%2Frustlings&ref=main)
|
||||
|
||||
## Manually
|
||||
|
||||
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 5.4.0)
|
||||
git clone -b 5.4.0 --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.4.1)
|
||||
git clone -b 5.4.1 --depth 1 https://github.com/rust-lang/rustlings
|
||||
cd rustlings
|
||||
cargo install --force --path .
|
||||
```
|
||||
@@ -155,8 +155,7 @@ for you:
|
||||
rm -rf rustlings # or your custom folder name, if you chose and or renamed it
|
||||
```
|
||||
|
||||
Second, since Rustlings got installed via `cargo install`, it's only reasonable to assume that you can also remove it using Cargo, and
|
||||
exactly that is the case. Run `cargo uninstall` to remove the `rustlings` binary:
|
||||
Second, run `cargo uninstall` to remove the `rustlings` binary:
|
||||
|
||||
```bash
|
||||
cargo uninstall rustlings
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
// 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
|
||||
// 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
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
// I AM NOT DONE
|
||||
|
||||
fn main () {
|
||||
fn main() {
|
||||
let my_fav_fruits = vec!["banana", "custard apple", "avocado", "peach", "raspberry"];
|
||||
|
||||
let mut my_iterable_fav_fruits = ???; // TODO: Step 1
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
// I AM NOT DONE
|
||||
|
||||
#[rustfmt::skip]
|
||||
macro_rules! my_macro {
|
||||
() => {
|
||||
println!("Check out my macro!");
|
||||
|
||||
@@ -32,7 +32,7 @@ fn main() {
|
||||
for offset in 0..8 {
|
||||
let child_numbers = // TODO
|
||||
joinhandles.push(thread::spawn(move || {
|
||||
let sum: u32 = child_numbers.iter().filter(|n| *n % 8 == offset).sum();
|
||||
let sum: u32 = child_numbers.iter().filter(|&&n| n % 8 == offset).sum();
|
||||
println!("Sum of offset {} is {}", offset, sum);
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
// 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.
|
||||
//
|
||||
// This exercise is meant to show you what to expect when passing data to Cow.
|
||||
// Fix the unit tests by checking for Cow::Owned(_) and Cow::Borrowed(_) at the TODO markers.
|
||||
|
||||
// I AM NOT DONE
|
||||
|
||||
@@ -20,29 +23,52 @@ fn abs_all<'a, 'b>(input: &'a mut Cow<'b, [i32]>) -> &'a mut Cow<'b, [i32]> {
|
||||
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"),
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn reference_mutation() -> Result<(), &'static str> {
|
||||
// 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(_) => Ok(()),
|
||||
_ => Err("Expected owned 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"),
|
||||
#[test]
|
||||
fn reference_no_mutation() -> Result<(), &'static str> {
|
||||
// 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) {
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
|
||||
// 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"),
|
||||
#[test]
|
||||
fn owned_no_mutation() -> Result<(), &'static str> {
|
||||
// We can also pass `slice` without `&` so Cow owns it directly.
|
||||
// In this case no mutation occurs and thus also no clone,
|
||||
// but the result is still owned because it always was.
|
||||
let slice = vec![0, 1, 2];
|
||||
let mut input = Cow::from(slice);
|
||||
match abs_all(&mut input) {
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn owned_mutation() -> Result<(), &'static str> {
|
||||
// Of course this is also the case if a mutation does occur.
|
||||
// In this case the call to `to_mut()` returns a reference to
|
||||
// the same data as before.
|
||||
let slice = vec![-1, 0, 1];
|
||||
let mut input = Cow::from(slice);
|
||||
match abs_all(&mut input) {
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,3 +13,5 @@ the other useful data structure, hash maps, later.
|
||||
## Further information
|
||||
|
||||
- [Storing Lists of Values with Vectors](https://doc.rust-lang.org/stable/book/ch08-01-vectors.html)
|
||||
- [`iter_mut`](https://doc.rust-lang.org/std/primitive.slice.html#method.iter_mut)
|
||||
- [`map`](https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.map)
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
rustlings =
|
||||
pkgs.rustPlatform.buildRustPackage {
|
||||
name = "rustlings";
|
||||
version = "5.4.0";
|
||||
version = "5.4.1";
|
||||
|
||||
buildInputs = cargoBuildInputs;
|
||||
|
||||
|
||||
@@ -1010,11 +1010,11 @@ https://doc.rust-lang.org/stable/book/ch16-00-concurrency.html
|
||||
[[exercises]]
|
||||
name = "cow1"
|
||||
path = "exercises/smart_pointers/cow1.rs"
|
||||
mode = "compile"
|
||||
mode = "test"
|
||||
hint = """
|
||||
Since the vector is already owned, the `Cow` type doesn't need to clone it.
|
||||
If Cow already owns the data it doesn't need to clone it when to_mut() is called.
|
||||
|
||||
Checkout https://doc.rust-lang.org/std/borrow/enum.Cow.html for documentation
|
||||
Check out https://doc.rust-lang.org/std/borrow/enum.Cow.html for documentation
|
||||
on the `Cow` type.
|
||||
"""
|
||||
|
||||
|
||||
@@ -141,7 +141,7 @@ git clone -q https://github.com/rust-lang/rustlings "$Path"
|
||||
|
||||
cd "$Path"
|
||||
|
||||
Version=$(curl -s https://api.github.com/repos/rust-lang/rustlings/releases/latest | ${PY} -c "import json,sys;obj=json.load(sys.stdin);print(obj['tag_name']);")
|
||||
Version=$(curl -s https://api.github.com/repos/rust-lang/rustlings/releases/latest | ${PY} -c "import json,sys;obj=json.load(sys.stdin);print(obj['tag_name']) if 'tag_name' in obj else sys.exit(f\"Error: {obj['message']}\");")
|
||||
CargoBin="${CARGO_HOME:-$HOME/.cargo}/bin"
|
||||
|
||||
if [[ -z ${Version} ]]
|
||||
|
||||
@@ -26,7 +26,7 @@ mod run;
|
||||
mod verify;
|
||||
|
||||
// In sync with crate version
|
||||
const VERSION: &str = "5.4.0";
|
||||
const VERSION: &str = "5.4.1";
|
||||
|
||||
#[derive(FromArgs, PartialEq, Debug)]
|
||||
/// Rustlings is a collection of small exercises to get you used to writing and reading Rust code
|
||||
|
||||
@@ -13,14 +13,15 @@ pub fn verify<'a>(
|
||||
progress: (usize, usize),
|
||||
verbose: bool,
|
||||
) -> Result<(), &'a Exercise> {
|
||||
let (mut num_done, total) = progress;
|
||||
let (num_done, total) = progress;
|
||||
let bar = ProgressBar::new(total as u64);
|
||||
let mut percentage = num_done as f32 / total as f32 * 100.0;
|
||||
bar.set_style(ProgressStyle::default_bar()
|
||||
.template("Progress: [{bar:60.green/red}] {pos}/{len} {msg}")
|
||||
.progress_chars("#>-")
|
||||
);
|
||||
bar.set_position(num_done as u64);
|
||||
bar.set_message(format!("({:.1} %)", 0.));
|
||||
bar.set_message(format!("({:.1} %)", percentage));
|
||||
|
||||
for exercise in exercises {
|
||||
let compile_result = match exercise.mode {
|
||||
@@ -31,8 +32,7 @@ pub fn verify<'a>(
|
||||
if !compile_result.unwrap_or(false) {
|
||||
return Err(exercise);
|
||||
}
|
||||
num_done += 1;
|
||||
let percentage = num_done as f32 / total as f32 * 100.0;
|
||||
percentage += 100.0 / total as f32;
|
||||
bar.inc(1);
|
||||
bar.set_message(format!("({:.1} %)", percentage));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user