mirror of
https://github.com/rust-lang/rustlings.git
synced 2026-01-12 13:49:19 +00:00
Merge branch 'rust-lang:main' into main
This commit is contained in:
commit
4faeeb807c
@ -1722,6 +1722,33 @@
|
|||||||
"contributions": [
|
"contributions": [
|
||||||
"content"
|
"content"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "seporterfield",
|
||||||
|
"name": "seporterfield",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/107010978?v=4",
|
||||||
|
"profile": "https://github.com/seporterfield",
|
||||||
|
"contributions": [
|
||||||
|
"content"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "dbarrosop",
|
||||||
|
"name": "David Barroso",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/6246622?v=4",
|
||||||
|
"profile": "https://www.linkedin.com/in/dbarrosop",
|
||||||
|
"contributions": [
|
||||||
|
"infra"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "tklauser",
|
||||||
|
"name": "Tobias Klauser",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/539708?v=4",
|
||||||
|
"profile": "https://distanz.ch",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"contributorsPerLine": 8,
|
"contributorsPerLine": 8,
|
||||||
|
|||||||
@ -245,6 +245,9 @@ authors.
|
|||||||
<td align="center"><a href="https://github.com/craymel"><img src="https://avatars.githubusercontent.com/u/71062756?v=4?s=100" width="100px;" alt="craymel"/><br /><sub><b>craymel</b></sub></a><br /><a href="#content-craymel" title="Content">🖋</a></td>
|
<td align="center"><a href="https://github.com/craymel"><img src="https://avatars.githubusercontent.com/u/71062756?v=4?s=100" width="100px;" alt="craymel"/><br /><sub><b>craymel</b></sub></a><br /><a href="#content-craymel" title="Content">🖋</a></td>
|
||||||
<td align="center"><a href="https://github.com/tkburis"><img src="https://avatars.githubusercontent.com/u/20501289?v=4?s=100" width="100px;" alt="TK Buristrakul"/><br /><sub><b>TK Buristrakul</b></sub></a><br /><a href="#content-tkburis" title="Content">🖋</a></td>
|
<td align="center"><a href="https://github.com/tkburis"><img src="https://avatars.githubusercontent.com/u/20501289?v=4?s=100" width="100px;" alt="TK Buristrakul"/><br /><sub><b>TK Buristrakul</b></sub></a><br /><a href="#content-tkburis" title="Content">🖋</a></td>
|
||||||
<td align="center"><a href="https://github.com/HerschelW"><img src="https://avatars.githubusercontent.com/u/17935816?v=4?s=100" width="100px;" alt="Kent Worthington"/><br /><sub><b>Kent Worthington</b></sub></a><br /><a href="#content-HerschelW" title="Content">🖋</a></td>
|
<td align="center"><a href="https://github.com/HerschelW"><img src="https://avatars.githubusercontent.com/u/17935816?v=4?s=100" width="100px;" alt="Kent Worthington"/><br /><sub><b>Kent Worthington</b></sub></a><br /><a href="#content-HerschelW" title="Content">🖋</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/seporterfield"><img src="https://avatars.githubusercontent.com/u/107010978?v=4?s=100" width="100px;" alt="seporterfield"/><br /><sub><b>seporterfield</b></sub></a><br /><a href="#content-seporterfield" title="Content">🖋</a></td>
|
||||||
|
<td align="center"><a href="https://www.linkedin.com/in/dbarrosop"><img src="https://avatars.githubusercontent.com/u/6246622?v=4?s=100" width="100px;" alt="David Barroso"/><br /><sub><b>David Barroso</b></sub></a><br /><a href="#infra-dbarrosop" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a></td>
|
||||||
|
<td align="center"><a href="https://distanz.ch"><img src="https://avatars.githubusercontent.com/u/539708?v=4?s=100" width="100px;" alt="Tobias Klauser"/><br /><sub><b>Tobias Klauser</b></sub></a><br /><a href="https://github.com/rust-lang/rustlings/commits?author=tklauser" title="Code">💻</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
| if | §3.5 |
|
| if | §3.5 |
|
||||||
| primitive_types | §3.2, §4.3 |
|
| primitive_types | §3.2, §4.3 |
|
||||||
| vecs | §8.1 |
|
| vecs | §8.1 |
|
||||||
| move_semantics | §4.1, §4.2 |
|
| move_semantics | §4.1-2 |
|
||||||
| structs | §5.1, §5.3 |
|
| structs | §5.1, §5.3 |
|
||||||
| enums | §6, §18.3 |
|
| enums | §6, §18.3 |
|
||||||
| strings | §8.2 |
|
| strings | §8.2 |
|
||||||
@ -19,8 +19,9 @@
|
|||||||
| traits | §10.2 |
|
| traits | §10.2 |
|
||||||
| tests | §11.1 |
|
| tests | §11.1 |
|
||||||
| lifetimes | §10.3 |
|
| lifetimes | §10.3 |
|
||||||
| standard_library_types | §13.2, §15.1, §16.3 |
|
| iterators | §13.2-4 |
|
||||||
| threads | §16.1, §16.2, §16.3 |
|
| threads | §16.1-3 |
|
||||||
|
| smart_pointers | §15, §16.3 |
|
||||||
| macros | §19.6 |
|
| macros | §19.6 |
|
||||||
| clippy | n/a |
|
| clippy | §21.4 |
|
||||||
| conversions | n/a |
|
| conversions | n/a |
|
||||||
|
|||||||
8
exercises/iterators/README.md
Normal file
8
exercises/iterators/README.md
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# Iterators
|
||||||
|
|
||||||
|
This section will teach you about Iterators.
|
||||||
|
|
||||||
|
## Further information
|
||||||
|
|
||||||
|
- [Iterator](https://doc.rust-lang.org/book/ch13-02-iterators.html)
|
||||||
|
- [Iterator documentation](https://doc.rust-lang.org/stable/std/iter/)
|
||||||
11
exercises/smart_pointers/README.md
Normal file
11
exercises/smart_pointers/README.md
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# Smart Pointers
|
||||||
|
In Rust, smart pointers are variables that contain an address in memory and reference some other data, but they also have additional metadata and capabilities.
|
||||||
|
Smart pointers in Rust often own the data they point to, while references only borrow data.
|
||||||
|
|
||||||
|
## Further Information
|
||||||
|
|
||||||
|
- [Smart Pointers](https://doc.rust-lang.org/book/ch15-00-smart-pointers.html)
|
||||||
|
- [Using Box to Point to Data on the Heap](https://doc.rust-lang.org/book/ch15-01-box.html)
|
||||||
|
- [Rc\<T\>, the Reference Counted Smart Pointer](https://doc.rust-lang.org/book/ch15-04-rc.html)
|
||||||
|
- [Shared-State Concurrency](https://doc.rust-lang.org/book/ch16-03-shared-state.html)
|
||||||
|
- [Cow Documentation](https://doc.rust-lang.org/std/borrow/enum.Cow.html)
|
||||||
@ -1,10 +0,0 @@
|
|||||||
# Standard library types
|
|
||||||
|
|
||||||
This section will teach you about Box, Shared-State Concurrency and Iterators.
|
|
||||||
|
|
||||||
## 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/)
|
|
||||||
13
flake.nix
13
flake.nix
@ -14,11 +14,18 @@
|
|||||||
flake-utils.lib.eachDefaultSystem (system:
|
flake-utils.lib.eachDefaultSystem (system:
|
||||||
let
|
let
|
||||||
pkgs = nixpkgs.legacyPackages.${system};
|
pkgs = nixpkgs.legacyPackages.${system};
|
||||||
|
|
||||||
|
cargoBuildInputs = with pkgs; lib.optionals stdenv.isDarwin [
|
||||||
|
darwin.apple_sdk.frameworks.CoreServices
|
||||||
|
];
|
||||||
|
|
||||||
rustlings =
|
rustlings =
|
||||||
pkgs.rustPlatform.buildRustPackage {
|
pkgs.rustPlatform.buildRustPackage {
|
||||||
name = "rustlings";
|
name = "rustlings";
|
||||||
version = "5.3.0";
|
version = "5.3.0";
|
||||||
|
|
||||||
|
buildInputs = cargoBuildInputs;
|
||||||
|
|
||||||
src = with pkgs.lib; cleanSourceWith {
|
src = with pkgs.lib; cleanSourceWith {
|
||||||
src = self;
|
src = self;
|
||||||
# a function that returns a bool determining if the path should be included in the cleaned source
|
# a function that returns a bool determining if the path should be included in the cleaned source
|
||||||
@ -42,12 +49,16 @@
|
|||||||
in
|
in
|
||||||
{
|
{
|
||||||
devShell = pkgs.mkShell {
|
devShell = pkgs.mkShell {
|
||||||
|
RUST_SRC_PATH = "${pkgs.rust.packages.stable.rustPlatform.rustLibSrc}";
|
||||||
|
|
||||||
buildInputs = with pkgs; [
|
buildInputs = with pkgs; [
|
||||||
cargo
|
cargo
|
||||||
rustc
|
rustc
|
||||||
rust-analyzer
|
rust-analyzer
|
||||||
rustlings
|
rustlings
|
||||||
];
|
rustfmt
|
||||||
|
clippy
|
||||||
|
] ++ cargoBuildInputs;
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
132
info.toml
132
info.toml
@ -809,7 +809,7 @@ If you use a lifetime annotation in a struct's fields, where else does it need t
|
|||||||
|
|
||||||
[[exercises]]
|
[[exercises]]
|
||||||
name = "iterators1"
|
name = "iterators1"
|
||||||
path = "exercises/standard_library_types/iterators1.rs"
|
path = "exercises/iterators/iterators1.rs"
|
||||||
mode = "compile"
|
mode = "compile"
|
||||||
hint = """
|
hint = """
|
||||||
Step 1:
|
Step 1:
|
||||||
@ -826,7 +826,7 @@ https://doc.rust-lang.org/std/iter/trait.Iterator.html for some ideas.
|
|||||||
|
|
||||||
[[exercises]]
|
[[exercises]]
|
||||||
name = "iterators2"
|
name = "iterators2"
|
||||||
path = "exercises/standard_library_types/iterators2.rs"
|
path = "exercises/iterators/iterators2.rs"
|
||||||
mode = "test"
|
mode = "test"
|
||||||
hint = """
|
hint = """
|
||||||
Step 1
|
Step 1
|
||||||
@ -847,7 +847,7 @@ and very general. Rust just needs to know the desired type."""
|
|||||||
|
|
||||||
[[exercises]]
|
[[exercises]]
|
||||||
name = "iterators3"
|
name = "iterators3"
|
||||||
path = "exercises/standard_library_types/iterators3.rs"
|
path = "exercises/iterators/iterators3.rs"
|
||||||
mode = "test"
|
mode = "test"
|
||||||
hint = """
|
hint = """
|
||||||
The divide function needs to return the correct error when even division is not
|
The divide function needs to return the correct error when even division is not
|
||||||
@ -866,7 +866,7 @@ can make the solution to this exercise infinitely easier."""
|
|||||||
|
|
||||||
[[exercises]]
|
[[exercises]]
|
||||||
name = "iterators4"
|
name = "iterators4"
|
||||||
path = "exercises/standard_library_types/iterators4.rs"
|
path = "exercises/iterators/iterators4.rs"
|
||||||
mode = "test"
|
mode = "test"
|
||||||
hint = """
|
hint = """
|
||||||
In an imperative language, you might write a for loop that updates
|
In an imperative language, you might write a for loop that updates
|
||||||
@ -878,7 +878,7 @@ Hint 2: Check out the `fold` and `rfold` methods!"""
|
|||||||
|
|
||||||
[[exercises]]
|
[[exercises]]
|
||||||
name = "iterators5"
|
name = "iterators5"
|
||||||
path = "exercises/standard_library_types/iterators5.rs"
|
path = "exercises/iterators/iterators5.rs"
|
||||||
mode = "test"
|
mode = "test"
|
||||||
hint = """
|
hint = """
|
||||||
The documentation for the std::iter::Iterator trait contains numerous methods
|
The documentation for the std::iter::Iterator trait contains numerous methods
|
||||||
@ -895,66 +895,6 @@ The fold method can be useful in the count_collection_iterator function.
|
|||||||
For a further challenge, consult the documentation for Iterator to find
|
For a further challenge, consult the documentation for Iterator to find
|
||||||
a different method that could make your code more compact than using fold."""
|
a different method that could make your code more compact than using fold."""
|
||||||
|
|
||||||
[[exercises]]
|
|
||||||
name = "box1"
|
|
||||||
path = "exercises/standard_library_types/box1.rs"
|
|
||||||
mode = "test"
|
|
||||||
hint = """
|
|
||||||
Step 1
|
|
||||||
The compiler's message should help: since we cannot store the value of the actual type
|
|
||||||
when working with recursive types, we need to store a reference (pointer) to its value.
|
|
||||||
We should, therefore, place our `List` inside a `Box`. More details in the book here:
|
|
||||||
https://doc.rust-lang.org/book/ch15-01-box.html#enabling-recursive-types-with-boxes
|
|
||||||
|
|
||||||
Step 2
|
|
||||||
Creating an empty list should be fairly straightforward (hint: peek at the assertions).
|
|
||||||
For a non-empty list keep in mind that we want to use our Cons "list builder".
|
|
||||||
Although the current list is one of integers (i32), feel free to change the definition
|
|
||||||
and try other types!
|
|
||||||
"""
|
|
||||||
|
|
||||||
[[exercises]]
|
|
||||||
name = "arc1"
|
|
||||||
path = "exercises/standard_library_types/arc1.rs"
|
|
||||||
mode = "compile"
|
|
||||||
hint = """
|
|
||||||
Make `shared_numbers` be an `Arc` from the numbers vector. Then, in order
|
|
||||||
to avoid creating a copy of `numbers`, you'll need to create `child_numbers`
|
|
||||||
inside the loop but still in the main thread.
|
|
||||||
|
|
||||||
`child_numbers` should be a clone of the Arc of the numbers instead of a
|
|
||||||
thread-local copy of the numbers.
|
|
||||||
|
|
||||||
This is a simple exercise if you understand the underlying concepts, but if this
|
|
||||||
is too much of a struggle, consider reading through all of Chapter 16 in the book:
|
|
||||||
https://doc.rust-lang.org/stable/book/ch16-00-concurrency.html
|
|
||||||
"""
|
|
||||||
|
|
||||||
[[exercises]]
|
|
||||||
name = "rc1"
|
|
||||||
path = "exercises/standard_library_types/rc1.rs"
|
|
||||||
mode = "compile"
|
|
||||||
hint = """
|
|
||||||
This is a straightforward exercise to use the Rc<T> type. Each Planet has
|
|
||||||
ownership of the Sun, and uses Rc::clone() to increment the reference count of the Sun.
|
|
||||||
After using drop() to move the Planets out of scope individually, the reference count goes down.
|
|
||||||
In the end the sun only has one reference again, to itself. See more at:
|
|
||||||
https://doc.rust-lang.org/book/ch15-04-rc.html
|
|
||||||
|
|
||||||
* Unfortunately 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]]
|
||||||
@ -1016,6 +956,68 @@ 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.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# SMART POINTERS
|
||||||
|
|
||||||
|
[[exercises]]
|
||||||
|
name = "box1"
|
||||||
|
path = "exercises/smart_pointers/box1.rs"
|
||||||
|
mode = "test"
|
||||||
|
hint = """
|
||||||
|
Step 1
|
||||||
|
The compiler's message should help: since we cannot store the value of the actual type
|
||||||
|
when working with recursive types, we need to store a reference (pointer) to its value.
|
||||||
|
We should, therefore, place our `List` inside a `Box`. More details in the book here:
|
||||||
|
https://doc.rust-lang.org/book/ch15-01-box.html#enabling-recursive-types-with-boxes
|
||||||
|
|
||||||
|
Step 2
|
||||||
|
Creating an empty list should be fairly straightforward (hint: peek at the assertions).
|
||||||
|
For a non-empty list keep in mind that we want to use our Cons "list builder".
|
||||||
|
Although the current list is one of integers (i32), feel free to change the definition
|
||||||
|
and try other types!
|
||||||
|
"""
|
||||||
|
|
||||||
|
[[exercises]]
|
||||||
|
name = "rc1"
|
||||||
|
path = "exercises/smart_pointers/rc1.rs"
|
||||||
|
mode = "compile"
|
||||||
|
hint = """
|
||||||
|
This is a straightforward exercise to use the Rc<T> type. Each Planet has
|
||||||
|
ownership of the Sun, and uses Rc::clone() to increment the reference count of the Sun.
|
||||||
|
After using drop() to move the Planets out of scope individually, the reference count goes down.
|
||||||
|
In the end the sun only has one reference again, to itself. See more at:
|
||||||
|
https://doc.rust-lang.org/book/ch15-04-rc.html
|
||||||
|
|
||||||
|
* Unfortunately Pluto is no longer considered a planet :(
|
||||||
|
"""
|
||||||
|
|
||||||
|
[[exercises]]
|
||||||
|
name = "arc1"
|
||||||
|
path = "exercises/smart_pointers/arc1.rs"
|
||||||
|
mode = "compile"
|
||||||
|
hint = """
|
||||||
|
Make `shared_numbers` be an `Arc` from the numbers vector. Then, in order
|
||||||
|
to avoid creating a copy of `numbers`, you'll need to create `child_numbers`
|
||||||
|
inside the loop but still in the main thread.
|
||||||
|
|
||||||
|
`child_numbers` should be a clone of the Arc of the numbers instead of a
|
||||||
|
thread-local copy of the numbers.
|
||||||
|
|
||||||
|
This is a simple exercise if you understand the underlying concepts, but if this
|
||||||
|
is too much of a struggle, consider reading through all of Chapter 16 in the book:
|
||||||
|
https://doc.rust-lang.org/stable/book/ch16-00-concurrency.html
|
||||||
|
"""
|
||||||
|
|
||||||
|
[[exercises]]
|
||||||
|
name = "cow1"
|
||||||
|
path = "exercises/smart_pointers/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.
|
||||||
|
"""
|
||||||
|
|
||||||
# MACROS
|
# MACROS
|
||||||
|
|
||||||
[[exercises]]
|
[[exercises]]
|
||||||
|
|||||||
@ -239,7 +239,7 @@ fn main() {
|
|||||||
.get_sysroot_src()
|
.get_sysroot_src()
|
||||||
.expect("Couldn't find toolchain path, do you have `rustc` installed?");
|
.expect("Couldn't find toolchain path, do you have `rustc` installed?");
|
||||||
project
|
project
|
||||||
.exercies_to_json()
|
.exercises_to_json()
|
||||||
.expect("Couldn't parse rustlings exercises files");
|
.expect("Couldn't parse rustlings exercises files");
|
||||||
|
|
||||||
if project.crates.is_empty() {
|
if project.crates.is_empty() {
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
use glob::glob;
|
use glob::glob;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::env;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
|
||||||
@ -54,7 +55,7 @@ impl RustAnalyzerProject {
|
|||||||
/// Parse the exercises folder for .rs files, any matches will create
|
/// Parse the exercises folder for .rs files, any matches will create
|
||||||
/// a new `crate` in rust-project.json which allows rust-analyzer to
|
/// a new `crate` in rust-project.json which allows rust-analyzer to
|
||||||
/// treat it like a normal binary
|
/// treat it like a normal binary
|
||||||
pub fn exercies_to_json(&mut self) -> Result<(), Box<dyn Error>> {
|
pub fn exercises_to_json(&mut self) -> Result<(), Box<dyn Error>> {
|
||||||
for e in glob("./exercises/**/*")? {
|
for e in glob("./exercises/**/*")? {
|
||||||
let path = e?.to_string_lossy().to_string();
|
let path = e?.to_string_lossy().to_string();
|
||||||
self.path_to_json(path);
|
self.path_to_json(path);
|
||||||
@ -64,6 +65,12 @@ impl RustAnalyzerProject {
|
|||||||
|
|
||||||
/// Use `rustc` to determine the default toolchain
|
/// Use `rustc` to determine the default toolchain
|
||||||
pub fn get_sysroot_src(&mut self) -> Result<(), Box<dyn Error>> {
|
pub fn get_sysroot_src(&mut self) -> Result<(), Box<dyn Error>> {
|
||||||
|
// check if RUST_SRC_PATH is set
|
||||||
|
if let Ok(path) = env::var("RUST_SRC_PATH") {
|
||||||
|
self.sysroot_src = path;
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
let toolchain = Command::new("rustc")
|
let toolchain = Command::new("rustc")
|
||||||
.arg("--print")
|
.arg("--print")
|
||||||
.arg("sysroot")
|
.arg("sysroot")
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user