diff --git a/.all-contributorsrc b/.all-contributorsrc index 97d38f5b..66056aa7 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -1722,6 +1722,33 @@ "contributions": [ "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, diff --git a/AUTHORS.md b/AUTHORS.md index 160eed57..06b56818 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -245,6 +245,9 @@ authors. craymel
craymel

🖋 TK Buristrakul
TK Buristrakul

🖋 Kent Worthington
Kent Worthington

🖋 + seporterfield
seporterfield

🖋 + David Barroso
David Barroso

🚇 + Tobias Klauser
Tobias Klauser

💻 diff --git a/exercises/README.md b/exercises/README.md index e52137ca..c7effa95 100644 --- a/exercises/README.md +++ b/exercises/README.md @@ -7,7 +7,7 @@ | if | §3.5 | | primitive_types | §3.2, §4.3 | | vecs | §8.1 | -| move_semantics | §4.1, §4.2 | +| move_semantics | §4.1-2 | | structs | §5.1, §5.3 | | enums | §6, §18.3 | | strings | §8.2 | @@ -19,8 +19,9 @@ | traits | §10.2 | | tests | §11.1 | | lifetimes | §10.3 | -| standard_library_types | §13.2, §15.1, §16.3 | -| threads | §16.1, §16.2, §16.3 | +| iterators | §13.2-4 | +| threads | §16.1-3 | +| smart_pointers | §15, §16.3 | | macros | §19.6 | -| clippy | n/a | +| clippy | §21.4 | | conversions | n/a | diff --git a/exercises/iterators/README.md b/exercises/iterators/README.md new file mode 100644 index 00000000..0e8b671e --- /dev/null +++ b/exercises/iterators/README.md @@ -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/) diff --git a/exercises/standard_library_types/iterators1.rs b/exercises/iterators/iterators1.rs similarity index 100% rename from exercises/standard_library_types/iterators1.rs rename to exercises/iterators/iterators1.rs diff --git a/exercises/standard_library_types/iterators2.rs b/exercises/iterators/iterators2.rs similarity index 100% rename from exercises/standard_library_types/iterators2.rs rename to exercises/iterators/iterators2.rs diff --git a/exercises/standard_library_types/iterators3.rs b/exercises/iterators/iterators3.rs similarity index 100% rename from exercises/standard_library_types/iterators3.rs rename to exercises/iterators/iterators3.rs diff --git a/exercises/standard_library_types/iterators4.rs b/exercises/iterators/iterators4.rs similarity index 100% rename from exercises/standard_library_types/iterators4.rs rename to exercises/iterators/iterators4.rs diff --git a/exercises/standard_library_types/iterators5.rs b/exercises/iterators/iterators5.rs similarity index 100% rename from exercises/standard_library_types/iterators5.rs rename to exercises/iterators/iterators5.rs diff --git a/exercises/smart_pointers/README.md b/exercises/smart_pointers/README.md new file mode 100644 index 00000000..c517ae31 --- /dev/null +++ b/exercises/smart_pointers/README.md @@ -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\, 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) diff --git a/exercises/standard_library_types/arc1.rs b/exercises/smart_pointers/arc1.rs similarity index 100% rename from exercises/standard_library_types/arc1.rs rename to exercises/smart_pointers/arc1.rs diff --git a/exercises/standard_library_types/box1.rs b/exercises/smart_pointers/box1.rs similarity index 100% rename from exercises/standard_library_types/box1.rs rename to exercises/smart_pointers/box1.rs diff --git a/exercises/standard_library_types/cow1.rs b/exercises/smart_pointers/cow1.rs similarity index 100% rename from exercises/standard_library_types/cow1.rs rename to exercises/smart_pointers/cow1.rs diff --git a/exercises/standard_library_types/rc1.rs b/exercises/smart_pointers/rc1.rs similarity index 100% rename from exercises/standard_library_types/rc1.rs rename to exercises/smart_pointers/rc1.rs diff --git a/exercises/standard_library_types/README.md b/exercises/standard_library_types/README.md deleted file mode 100644 index 809d61fe..00000000 --- a/exercises/standard_library_types/README.md +++ /dev/null @@ -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/) diff --git a/flake.nix b/flake.nix index a6703199..2c29ffa5 100644 --- a/flake.nix +++ b/flake.nix @@ -14,11 +14,18 @@ flake-utils.lib.eachDefaultSystem (system: let pkgs = nixpkgs.legacyPackages.${system}; + + cargoBuildInputs = with pkgs; lib.optionals stdenv.isDarwin [ + darwin.apple_sdk.frameworks.CoreServices + ]; + rustlings = pkgs.rustPlatform.buildRustPackage { name = "rustlings"; version = "5.3.0"; + buildInputs = cargoBuildInputs; + src = with pkgs.lib; cleanSourceWith { src = self; # a function that returns a bool determining if the path should be included in the cleaned source @@ -42,12 +49,16 @@ in { devShell = pkgs.mkShell { + RUST_SRC_PATH = "${pkgs.rust.packages.stable.rustPlatform.rustLibSrc}"; + buildInputs = with pkgs; [ cargo rustc rust-analyzer rustlings - ]; + rustfmt + clippy + ] ++ cargoBuildInputs; }; }); } diff --git a/info.toml b/info.toml index 8356f6ab..1135c914 100644 --- a/info.toml +++ b/info.toml @@ -809,7 +809,7 @@ If you use a lifetime annotation in a struct's fields, where else does it need t [[exercises]] name = "iterators1" -path = "exercises/standard_library_types/iterators1.rs" +path = "exercises/iterators/iterators1.rs" mode = "compile" hint = """ Step 1: @@ -826,7 +826,7 @@ https://doc.rust-lang.org/std/iter/trait.Iterator.html for some ideas. [[exercises]] name = "iterators2" -path = "exercises/standard_library_types/iterators2.rs" +path = "exercises/iterators/iterators2.rs" mode = "test" hint = """ Step 1 @@ -847,7 +847,7 @@ and very general. Rust just needs to know the desired type.""" [[exercises]] name = "iterators3" -path = "exercises/standard_library_types/iterators3.rs" +path = "exercises/iterators/iterators3.rs" mode = "test" hint = """ 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]] name = "iterators4" -path = "exercises/standard_library_types/iterators4.rs" +path = "exercises/iterators/iterators4.rs" mode = "test" hint = """ 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]] name = "iterators5" -path = "exercises/standard_library_types/iterators5.rs" +path = "exercises/iterators/iterators5.rs" mode = "test" hint = """ 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 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 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 [[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. """ +# 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 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 [[exercises]] diff --git a/src/main.rs b/src/main.rs index 6dc18e8b..7e9156fb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -239,7 +239,7 @@ fn main() { .get_sysroot_src() .expect("Couldn't find toolchain path, do you have `rustc` installed?"); project - .exercies_to_json() + .exercises_to_json() .expect("Couldn't parse rustlings exercises files"); if project.crates.is_empty() { diff --git a/src/project.rs b/src/project.rs index 0df00b9a..6e483504 100644 --- a/src/project.rs +++ b/src/project.rs @@ -1,5 +1,6 @@ use glob::glob; use serde::{Deserialize, Serialize}; +use std::env; use std::error::Error; use std::process::Command; @@ -54,7 +55,7 @@ impl RustAnalyzerProject { /// Parse the exercises folder for .rs files, any matches will create /// a new `crate` in rust-project.json which allows rust-analyzer to /// treat it like a normal binary - pub fn exercies_to_json(&mut self) -> Result<(), Box> { + pub fn exercises_to_json(&mut self) -> Result<(), Box> { for e in glob("./exercises/**/*")? { let path = e?.to_string_lossy().to_string(); self.path_to_json(path); @@ -64,6 +65,12 @@ impl RustAnalyzerProject { /// Use `rustc` to determine the default toolchain pub fn get_sysroot_src(&mut self) -> Result<(), Box> { + // 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") .arg("--print") .arg("sysroot")