diff --git a/.cargo/config.toml b/.cargo/config.toml
new file mode 100644
index 00000000..b8fa3f77
--- /dev/null
+++ b/.cargo/config.toml
@@ -0,0 +1,2 @@
+[alias]
+dev = ["run", "--", "dev"]
diff --git a/.editorconfig b/.editorconfig
deleted file mode 100644
index aab09aa3..00000000
--- a/.editorconfig
+++ /dev/null
@@ -1,7 +0,0 @@
-root = true
-
-[*.rs]
-end_of_line = lf
-insert_final_newline = true
-indent_style = space
-indent_size = 4
diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml
index 80f052d6..0317f351 100644
--- a/.github/workflows/rust.yml
+++ b/.github/workflows/rust.yml
@@ -1,10 +1,16 @@
-name: Rustlings Tests
+name: Check
on:
push:
branches: [main]
+ paths-ignore:
+ - website
+ - '*.md'
pull_request:
branches: [main]
+ paths-ignore:
+ - website
+ - '*.md'
env:
CARGO_TERM_COLOR: always
@@ -14,30 +20,28 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- - run: cargo clippy -- --deny warnings
+ - name: Clippy
+ run: cargo clippy -- --deny warnings
fmt:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- - uses: DavidAnson/markdownlint-cli2-action@v16
- with:
- globs: "exercises/**/*.md"
- - name: Run cargo fmt
+ - name: rustfmt
run: cargo fmt --all --check
test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
- os: [ubuntu-latest, windows-latest, macOS-latest]
+ os: [ubuntu-latest, windows-latest, macos-latest]
steps:
- uses: actions/checkout@v4
- uses: swatinem/rust-cache@v2
- - name: Run cargo test
+ - name: cargo test
run: cargo test --workspace
dev-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: swatinem/rust-cache@v2
- - name: Run rustlings dev check
- run: cargo run -- dev check --require-solutions
+ - name: rustlings dev check
+ run: cargo dev check --require-solutions
diff --git a/.github/workflows/web.yml b/.github/workflows/web.yml
deleted file mode 100644
index ec5d4462..00000000
--- a/.github/workflows/web.yml
+++ /dev/null
@@ -1,87 +0,0 @@
-# Workflow to build your docs with oranda (and mdbook)
-# and deploy them to Github Pages
-name: Web
-
-# We're going to push to the gh-pages branch, so we need that permission
-permissions:
- contents: write
-
-# What situations do we want to build docs in?
-# All of these work independently and can be removed / commented out
-# if you don't want oranda/mdbook running in that situation
-on:
- # Check that a PR didn't break docs!
- #
- # Note that the "Deploy to Github Pages" step won't run in this mode,
- # so this won't have any side-effects. But it will tell you if a PR
- # completely broke oranda/mdbook. Sadly we don't provide previews (yet)!
- pull_request:
-
- # Whenever something gets pushed to main, update the docs!
- # This is great for getting docs changes live without cutting a full release.
- #
- # Note that if you're using cargo-dist, this will "race" the Release workflow
- # that actually builds the Github Release that oranda tries to read (and
- # this will almost certainly complete first). As a result you will publish
- # docs for the latest commit but the oranda landing page won't know about
- # the latest release. The workflow_run trigger below will properly wait for
- # cargo-dist, and so this half-published state will only last for ~10 minutes.
- #
- # If you only want docs to update with releases, disable this, or change it to
- # a "release" branch. You can, of course, also manually trigger a workflow run
- # when you want the docs to update.
- push:
- branches:
- - main
-
- # Whenever a workflow called "Release" completes, update the docs!
- #
- # If you're using cargo-dist, this is recommended, as it will ensure that
- # oranda always sees the latest release right when it's available. Note
- # however that Github's UI is wonky when you use workflow_run, and won't
- # show this workflow as part of any commit. You have to go to the "actions"
- # tab for your repo to see this one running (the gh-pages deploy will also
- # only show up there).
- workflow_run:
- workflows: [ "Release" ]
- types:
- - completed
-
-# Alright, let's do it!
-jobs:
- web:
- name: Build and deploy site and docs
- runs-on: ubuntu-latest
- steps:
- # Setup
- - uses: actions/checkout@v4
- with:
- fetch-depth: 0
- - uses: swatinem/rust-cache@v2
-
- # If you use any mdbook plugins, here's the place to install them!
-
- # Install and run oranda (and mdbook)
- # This will write all output to ./public/ (including copying mdbook's output to there)
- - name: Install and run oranda
- run: |
- curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/oranda/releases/download/v0.3.1/oranda-installer.sh | sh
- oranda build
-
- # Deploy to our gh-pages branch (creating it if it doesn't exist)
- # the "public" dir that oranda made above will become the root dir
- # of this branch.
- #
- # Note that once the gh-pages branch exists, you must
- # go into repo's settings > pages and set "deploy from branch: gh-pages"
- # the other defaults work fine.
- - name: Deploy to Github Pages
- uses: JamesIves/github-pages-deploy-action@v4.4.1
- # ONLY if we're on main (so no PRs or feature branches allowed!)
- if: ${{ github.ref == 'refs/heads/main' }}
- with:
- branch: gh-pages
- # Gotta tell the action where to find oranda's output
- folder: public
- token: ${{ secrets.GITHUB_TOKEN }}
- single-commit: true
diff --git a/.github/workflows/website.yml b/.github/workflows/website.yml
new file mode 100644
index 00000000..936cd562
--- /dev/null
+++ b/.github/workflows/website.yml
@@ -0,0 +1,43 @@
+name: Website
+
+on:
+ workflow_dispatch:
+ push:
+ branches: [main]
+ paths: [website]
+
+jobs:
+ build:
+ defaults:
+ run:
+ working-directory: website
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - name: Install TailwindCSS
+ run: npm install
+ - name: Build CSS
+ run: npx @tailwindcss/cli -m -i input.css -o static/main.css
+ - name: Download Zola
+ run: curl -fsSL https://github.com/getzola/zola/releases/download/v0.20.0/zola-v0.20.0-x86_64-unknown-linux-gnu.tar.gz | tar xz
+ - name: Build site
+ run: ./zola build
+ - name: Upload static files as artifact
+ uses: actions/upload-pages-artifact@v3
+ with:
+ path: website/public/
+
+ deploy:
+ needs: build
+ # Grant GITHUB_TOKEN the permissions required to make a Pages deployment
+ permissions:
+ pages: write # to deploy to Pages
+ id-token: write # to verify the deployment originates from an appropriate source
+ # Deploy to the github-pages environment
+ environment:
+ name: github-pages
+ url: ${{ steps.deployment.outputs.page_url }}
+ runs-on: ubuntu-latest
+ steps:
+ - name: Deploy to GitHub Pages
+ uses: actions/deploy-pages@v4
diff --git a/.gitignore b/.gitignore
index 945382c3..ea65eb1e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,10 +6,6 @@ Cargo.lock
# State file
.rustlings-state.txt
-# oranda
-public/
-.netlify
-
# OS
.DS_Store
.direnv/
diff --git a/.markdownlint.yml b/.markdownlint.yml
deleted file mode 100644
index d5f7e391..00000000
--- a/.markdownlint.yml
+++ /dev/null
@@ -1,2 +0,0 @@
-# MD013/line-length Line length, Expected: 80
-MD013: false
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 19bb8fc3..2d2b4153 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,56 @@
-
+## Unreleased
+
+### Changed
+
+- `vecs2`: Removed the use of `map` and `collect`, which are only taught later.
+
+## 6.5.0 (2025-08-21)
+
+### Added
+
+- Check that Clippy is installed before initialization
+
+### Changed
+
+- Upgrade to Rust edition 2024
+- Raise the minimum supported Rust version to `1.88`
+- Don't follow symlinks in the file watcher
+- `dev new`: Don't add `.rustlings-state.txt` to `.gitignore`
+
+### Fixed
+
+- Fix file links in VS Code
+- Fix error printing when the progress bar is shown
+- `dev check`: Don't check formatting if there are no solution files
+
+## 6.4.0 (2024-11-11)
+
+### Added
+
+- The list of exercises is now searchable by pressing `s` or `/` 🔍️ (thanks to [@frroossst](https://github.com/frroossst))
+- New option `c` in the prompt to manually check all exercises ✅ (thanks to [@Nahor](https://github.com/Nahor))
+- New command `check-all` to manually check all exercises ✅ (thanks to [@Nahor](https://github.com/Nahor))
+- Addictive animation for showing the progress of checking all exercises. A nice showcase of parallelism in Rust ✨
+- New option `x` in the prompt to reset the file of the current exercise 🔄
+- Allow `dead_code` for all exercises and solutions ⚰️ (thanks to [@huss4in](https://github.com/huss4in))
+- Pause input while running an exercise to avoid unexpected prompt interactions ⏸️
+- Limit the maximum number of exercises to 999. Any community exercises willing to reach that limit? 🔝
+
+### Changed
+
+- `enums3`: Remove redundant enum definition task (thanks to [@senekor](https://github.com/senekor))
+- `if2`: Make the exercise less confusing by avoiding "fizz", "fuzz", "foo", "bar" and "baz" (thanks to [@senekor](https://github.com/senekor))
+- `hashmap3`: Use the method `Entry::or_default`.
+- Update the state of all exercises when checking all of them (thanks to [@Nahor](https://github.com/Nahor))
+- The main prompt doesn't need a confirmation with ENTER on Unix-like systems anymore.
+- No more jumping back to a previous exercise when its file is changed. Use the list to jump between exercises.
+- Dump the solution file after an exercise is done even if the solution's directory doesn't exist.
+- Rework the footer in the list.
+- Optimize the file watcher.
+
+### Fixed
+
+- Fix bad contrast in the list on terminals with a light theme.
## 6.3.0 (2024-08-29)
@@ -39,8 +91,6 @@
- Fix the list when the terminal height is too low.
- Restore the terminal after an error in the list.
-
-
## 6.2.0 (2024-08-09)
### Added
@@ -57,13 +107,11 @@
- Run the final check of all exercises in parallel.
- Small exercise improvements.
-
-
## 6.1.0 (2024-07-10)
#### Added
-- `dev check`: Check that all exercises (including third-party ones) include at least one `TODO` comment.
+- `dev check`: Check that all exercises (including community ones) include at least one `TODO` comment.
- `dev check`: Check that all exercises actually fail to run (not already solved).
#### Changed
@@ -76,15 +124,11 @@
- Exit with a helpful error message on missing/unsupported terminal/TTY.
- Mark the last exercise as done.
-
-
## 6.0.1 (2024-07-04)
Small exercise improvements and fixes.
Most importantly, fixed that the exercise `clippy1` was already solved 😅
-
-
## 6.0.0 (2024-07-03)
This release is the result of a complete rewrite to deliver a ton of new features and improvements ✨
@@ -113,7 +157,7 @@ You can read about the motivations of this change in [this issue](https://github
### List mode
-A list mode was added using [Ratatui](https://ratatui.rs).
+A new list mode was added!
You can enter it by entering `l` in the watch mode.
It offers the following features:
@@ -142,15 +186,13 @@ This should avoid issues related to the language server or to running exercises,
Clippy lints are now shown on all exercises, not only the Clippy exercises 📎
Make Clippy your friend from early on 🥰
-### Third-party exercises
+### Community Exercises
-Rustlings now supports third-party exercises!
+Rustlings now supports community exercises!
Do you want to create your own set of Rustlings exercises to focus on some specific topic?
Or do you want to translate the original Rustlings exercises?
-Then follow the link to the guide about [third-party exercises](THIRD_PARTY_EXERCISES.md)!
-
-
+Then follow the link to the guide about [community exercises](https://rustlings.rust-lang.org/community-exercises)!
## 5.6.1 (2023-09-18)
@@ -167,8 +209,6 @@ Then follow the link to the guide about [third-party exercises](THIRD_PARTY_EXER
- `as_ref_mut`: Fixed a typo in a test function name.
- `enums3`: Fixed formatting with `rustfmt`.
-
-
## 5.6.0 (2023-09-04)
#### Added
@@ -208,16 +248,12 @@ Then follow the link to the guide about [third-party exercises](THIRD_PARTY_EXER
- Lots of Nix housekeeping that I don't feel qualified to write about!
- Improved CI workflows, we're now testing on multiple platforms at once.
-
-
## 5.5.1 (2023-05-17)
#### Fixed
- Reverted `rust-project.json` path generation due to an upstream `rust-analyzer` fix.
-
-
## 5.5.0 (2023-05-17)
#### Added
@@ -252,8 +288,6 @@ Then follow the link to the guide about [third-party exercises](THIRD_PARTY_EXER
- Added a markdown linter to run on GitHub actions
- Split quick installation section into two code blocks
-
-
## 5.4.1 (2023-03-10)
#### Changed
@@ -269,8 +303,6 @@ Then follow the link to the guide about [third-party exercises](THIRD_PARTY_EXER
- `macros4`: Prevented auto-fix by adding `#[rustfmt::skip]`
- `cli`: Actually show correct progress percentages
-
-
## 5.4.0 (2023-02-12)
#### Changed
@@ -299,8 +331,6 @@ Then follow the link to the guide about [third-party exercises](THIRD_PARTY_EXER
- Bumped min Rust version to 1.58 in installation script
-
-
## 5.3.0 (2022-12-23)
#### Added
@@ -333,8 +363,6 @@ Then follow the link to the guide about [third-party exercises](THIRD_PARTY_EXER
- Applied some Clippy and rustfmt formatting
- Added a note on Windows PowerShell and other shell compatibility
-
-
## 5.2.1 (2022-09-06)
#### Fixed
@@ -348,8 +376,6 @@ Then follow the link to the guide about [third-party exercises](THIRD_PARTY_EXER
- Fixed a typo in README.md
-
-
## 5.2.0 (2022-08-27)
#### Added
@@ -366,16 +392,12 @@ Then follow the link to the guide about [third-party exercises](THIRD_PARTY_EXER
- **quiz1**: Adjusted the explanations to be consistent with
the tests
-
-
## 5.1.1 (2022-08-17)
#### Bug Fixes
- Fixed an incorrect assertion in options1
-
-
## 5.1.0 (2022-08-16)
#### Features
@@ -410,8 +432,6 @@ Then follow the link to the guide about [third-party exercises](THIRD_PARTY_EXER
- Clarified manual installation instructions using `cargo install --path .`
- Added a link to our Zulip in the readme file
-
-
## 5.0.0 (2022-07-16)
#### Features
@@ -484,8 +504,6 @@ Then follow the link to the guide about [third-party exercises](THIRD_PARTY_EXER
- Updated spacing in Cargo.toml.
- Added a GitHub actions config so that tests run on every PR/commit.
-
-
## 4.8.0 (2022-07-01)
#### Features
@@ -506,8 +524,6 @@ Then follow the link to the guide about [third-party exercises](THIRD_PARTY_EXER
- Replaced the git.io URL with the fully qualified URL because of git.io's sunsetting.
- Removed the deprecated Rust GitPod extension.
-
-
## 4.7.1 (2022-04-20)
#### Features
@@ -528,8 +544,6 @@ Then follow the link to the guide about [third-party exercises](THIRD_PARTY_EXER
- The changelog will now be manually written instead of being automatically generated by the
Git log.
-
-
## 4.7.0 (2022-04-14)
#### Features
@@ -570,8 +584,6 @@ Then follow the link to the guide about [third-party exercises](THIRD_PARTY_EXER
- Add hints on how to get GCC installed (#741) ([bc56861](https://github.com/rust-lang/rustlings/commit/bc5686174463ad6f4f6b824b0e9b97c3039d4886))
- Fix some code blocks that were not highlighted ([17f9d74](https://github.com/rust-lang/rustlings/commit/17f9d7429ccd133a72e815fb5618e0ce79560929))
-
-
## 4.6.0 (2021-09-25)
#### Features
@@ -594,8 +606,6 @@ Then follow the link to the guide about [third-party exercises](THIRD_PARTY_EXER
- Clarify instructions ([df25684c](https://github.com/rust-lang/rustlings/commit/df25684cb79f8413915e00b5efef29369849cef1))
- **quiz1:** Fix inconsistent wording (#826) ([03131a3d](https://github.com/rust-lang/rustlings/commit/03131a3d35d9842598150f9da817f7cc26e2669a))
-
-
## 4.5.0 (2021-07-07)
#### Features
@@ -616,8 +626,6 @@ Then follow the link to the guide about [third-party exercises](THIRD_PARTY_EXER
- **try_from_into, from_str:** hints for dyn Error ([11d2cf0d](https://github.com/rust-lang/rustlings/commit/11d2cf0d604dee3f5023c17802d69438e69fa50e))
- **variables5:** confine the answer further ([48ffcbd2](https://github.com/rust-lang/rustlings/commit/48ffcbd2c4cc4d936c2c7480019190f179813cc5))
-
-
## 4.4.0 (2021-04-24)
#### Bug Fixes
@@ -659,8 +667,6 @@ Then follow the link to the guide about [third-party exercises](THIRD_PARTY_EXER
- updated progress percentage ([1c6f7e4b](https://github.com/rust-lang/rustlings/commit/1c6f7e4b7b9b3bd36f4da2bb2b69c549cc8bd913))
- added progress info ([c0e3daac](https://github.com/rust-lang/rustlings/commit/c0e3daacaf6850811df5bc57fa43e0f249d5cfa4))
-
-
## 4.3.0 (2020-12-29)
#### Features
@@ -683,8 +689,6 @@ Then follow the link to the guide about [third-party exercises](THIRD_PARTY_EXER
- Update description (#584) ([96347df9](https://github.com/rust-lang/rustlings/commit/96347df9df294f01153b29d9ad4ba361f665c755))
- **vec1:** Have test compare every element in a and v ([9b6c6293](https://github.com/rust-lang/rustlings/commit/9b6c629397b24b944f484f5b2bbd8144266b5695))
-
-
## 4.2.0 (2020-11-07)
#### Features
@@ -705,8 +709,6 @@ Then follow the link to the guide about [third-party exercises](THIRD_PARTY_EXER
- missing comma in test ([4fb230da](https://github.com/rust-lang/rustlings/commit/4fb230daf1251444fcf29e085cee222a91f8a37e))
- **quiz3:** Second test is for odd numbers, not even. (#553) ([18e0bfef](https://github.com/rust-lang/rustlings/commit/18e0bfef1de53071e353ba1ec5837002ff7290e6))
-
-
## 4.1.0 (2020-10-05)
#### Bug Fixes
@@ -729,8 +731,6 @@ Then follow the link to the guide about [third-party exercises](THIRD_PARTY_EXER
- **cli:** Added 'cls' command to 'watch' mode (#474) ([4f2468e1](https://github.com/rust-lang/rustlings/commit/4f2468e14f574a93a2e9b688367b5752ed96ae7b))
- **try_from_into:** Add insufficient length test (#469) ([523d18b8](https://github.com/rust-lang/rustlings/commit/523d18b873a319f7c09262f44bd40e2fab1830e5))
-
-
## 4.0.0 (2020-07-08)
#### Breaking Changes
@@ -772,8 +772,6 @@ Then follow the link to the guide about [third-party exercises](THIRD_PARTY_EXER
- **test2:** name of type String and &str (#394) ([d6c0a688](https://github.com/rust-lang/rustlings/commit/d6c0a688e6a96f93ad60d540d4b326f342fc0d45))
- **variables6:** minor typo (#419) ([524e17df](https://github.com/rust-lang/rustlings/commit/524e17df10db95f7b90a0f75cc8997182a8a4094))
-
-
## 3.0.0 (2020-04-11)
#### Breaking Changes
@@ -796,8 +794,6 @@ Then follow the link to the guide about [third-party exercises](THIRD_PARTY_EXER
- add new exercises for generics (#280) ([76be5e4e](https://github.com/rust-lang/rustlings/commit/76be5e4e991160f5fd9093f03ee2ba260e8f7229))
- **ci:** add buildkite config ([b049fa2c](https://github.com/rust-lang/rustlings/commit/b049fa2c84dba0f0c8906ac44e28fd45fba51a71))
-
-
### 2.2.1 (2020-02-27)
#### Bug Fixes
@@ -808,13 +804,11 @@ Then follow the link to the guide about [third-party exercises](THIRD_PARTY_EXER
- Add clippy lints (#269) ([1e2fd9c9](https://github.com/rust-lang/rustlings/commit/1e2fd9c92f8cd6e389525ca1a999fca4c90b5921))
-
-
## 2.2.0 (2020-02-25)
#### Bug Fixes
-- Update deps to version compatable with aarch64-pc-windows (#263) ([19a93428](https://github.com/rust-lang/rustlings/commit/19a93428b3c73d994292671f829bdc8e5b7b3401))
+- Update deps to version compatible with aarch64-pc-windows (#263) ([19a93428](https://github.com/rust-lang/rustlings/commit/19a93428b3c73d994292671f829bdc8e5b7b3401))
- **docs:**
- Added a necessary step to Windows installation process (#242) ([3906efcd](https://github.com/rust-lang/rustlings/commit/3906efcd52a004047b460ed548037093de3f523f))
- Fixed mangled sentence from book; edited for clarity (#266) ([ade52ff](https://github.com/rust-lang/rustlings/commit/ade52ffb739987287ddd5705944c8777705faed9))
@@ -837,8 +831,6 @@ Then follow the link to the guide about [third-party exercises](THIRD_PARTY_EXER
- Added traits exercises (#274 but specifically #216, which originally added
this :heart:) ([b559cdd](https://github.com/rust-lang/rustlings/commit/b559cdd73f32c0d0cfc1feda39f82b3e3583df17))
-
-
## 2.1.0 (2019-11-27)
#### Bug Fixes
@@ -856,8 +848,6 @@ Then follow the link to the guide about [third-party exercises](THIRD_PARTY_EXER
- **watch:** show hint while watching ([8143d57b](https://github.com/rust-lang/rustlings/commit/8143d57b4e88c51341dd4a18a14c536042cc009c))
-
-
## 2.0.0 (2019-11-12)
#### Bug Fixes
@@ -878,8 +868,6 @@ Then follow the link to the guide about [third-party exercises](THIRD_PARTY_EXER
- **cli:** check for rustc before doing anything ([36a033b8](https://github.com/rust-lang/rustlings/commit/36a033b87a6549c1e5639c908bf7381c84f4f425))
- **hint:** Add test for hint ([ce9fa6eb](https://github.com/rust-lang/rustlings/commit/ce9fa6ebbfdc3e7585d488d9409797285708316f))
-
-
### 1.5.1 (2019-11-11)
#### Bug Fixes
@@ -891,8 +879,6 @@ Then follow the link to the guide about [third-party exercises](THIRD_PARTY_EXER
- **threads:** Move Threads behind SLT ([fbe91a67](https://github.com/rust-lang/rustlings/commit/fbe91a67a482bfe64cbcdd58d06ba830a0f39da3), closes [#205](https://github.com/rust-lang/rustlings/issues/205))
- **watch:** clear screen before each `verify()` ([3aff590](https://github.com/rust-lang/rustlings/commit/3aff59085586c24196a547c2693adbdcf4432648))
-
-
## 1.5.0 (2019-11-09)
#### Bug Fixes
@@ -917,8 +903,6 @@ Then follow the link to the guide about [third-party exercises](THIRD_PARTY_EXER
- Added exercise for struct update syntax ([1c4c8764](https://github.com/rust-lang/rustlings/commit/1c4c8764ed118740cd4cee73272ddc6cceb9d959))
- **iterators2:** adds iterators2 exercise including config ([9288fccf](https://github.com/rust-lang/rustlings/commit/9288fccf07a2c5043b76d0fd6491e4cf72d76031))
-
-
### 1.4.1 (2019-08-13)
#### Bug Fixes
@@ -927,8 +911,6 @@ Then follow the link to the guide about [third-party exercises](THIRD_PARTY_EXER
- **option1:** Add test for prematurely passing exercise ([a750e4a1](https://github.com/rust-lang/rustlings/commit/a750e4a1a3006227292bb17d57d78ce84da6bfc6))
- **test1:** Swap assertion parameter order ([4086d463](https://github.com/rust-lang/rustlings/commit/4086d463a981e81d97781851d17db2ced290f446))
-
-
## 1.4.0 (2019-07-13)
#### Bug Fixes
@@ -945,8 +927,6 @@ Then follow the link to the guide about [third-party exercises](THIRD_PARTY_EXER
- **changelog:** Use clog for changelogs ([34e31232](https://github.com/rust-lang/rustlings/commit/34e31232dfddde284a341c9609b33cd27d9d5724))
- **iterators2:** adds iterators2 exercise including config ([9288fccf](https://github.com/rust-lang/rustlings/commit/9288fccf07a2c5043b76d0fd6491e4cf72d76031))
-
-
### 1.3.0 (2019-06-05)
#### Features
@@ -962,16 +942,12 @@ Then follow the link to the guide about [third-party exercises](THIRD_PARTY_EXER
- Fix broken link (#164, @HanKruiger)
- Remove highlighting and syntect (#167, @komaeda)
-
-
### 1.2.2 (2019-05-07)
#### Bug Fixes
- Reverted `--nocapture` flag since it was causing tests to pass unconditionally
-
-
### 1.2.1 (2019-04-22)
#### Bug Fixes
@@ -979,8 +955,6 @@ Then follow the link to the guide about [third-party exercises](THIRD_PARTY_EXER
- Fix the `--nocapture` feature (@komaeda)
- Provide a nicer error message for when you're in the wrong directory
-
-
### 1.2.0 (2019-04-22)
#### Features
@@ -988,8 +962,6 @@ Then follow the link to the guide about [third-party exercises](THIRD_PARTY_EXER
- Add errors to exercises that compile without user changes (@yvan-sraka)
- Use --nocapture when testing, enabling `println!` when running (@komaeda)
-
-
### 1.1.1 (2019-04-14)
#### Bug fixes
@@ -1002,8 +974,6 @@ Then follow the link to the guide about [third-party exercises](THIRD_PARTY_EXER
- Fix links by deleting book version (@diodfr, #142)
- Canonicalize paths to fix path matching (@cjpearce, #143)
-
-
### 1.1.0 (2019-03-20)
- errors2.rs: update link to Rust book (#124)
@@ -1013,16 +983,12 @@ Then follow the link to the guide about [third-party exercises](THIRD_PARTY_EXER
- Give a warning when Rustlings isn't run from the right directory (#123)
- Verify that rust version is recent enough to install Rustlings (#131)
-
-
### 1.0.1 (2019-03-06)
- Adds a way to install Rustlings in one command (`curl -L https://git.io/rustlings | bash`)
- Makes `rustlings watch` react to create file events (@shaunbennett, #117)
- Reworks the exercise management to use an external TOML file instead of just listing them in the code
-
-
### 1.0.0 (2019-03-06)
Initial release.
diff --git a/Cargo.lock b/Cargo.lock
index f89c139f..f883653f 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1,12 +1,12 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
-version = 3
+version = 4
[[package]]
name = "anstream"
-version = "0.6.15"
+version = "0.6.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526"
+checksum = "3ae563653d1938f79b1ab1b5e668c87c76a9930414574a6583a7b7e11a8e6192"
dependencies = [
"anstyle",
"anstyle-parse",
@@ -19,49 +19,50 @@ dependencies = [
[[package]]
name = "anstyle"
-version = "1.0.8"
+version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1"
+checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd"
[[package]]
name = "anstyle-parse"
-version = "0.2.5"
+version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb"
+checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
-version = "1.1.1"
+version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a"
+checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2"
dependencies = [
- "windows-sys 0.52.0",
+ "windows-sys 0.60.2",
]
[[package]]
name = "anstyle-wincon"
-version = "3.0.4"
+version = "3.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8"
+checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a"
dependencies = [
"anstyle",
- "windows-sys 0.52.0",
+ "once_cell_polyfill",
+ "windows-sys 0.60.2",
]
[[package]]
name = "anyhow"
-version = "1.0.89"
+version = "1.0.99"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6"
+checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100"
[[package]]
name = "autocfg"
-version = "1.4.0"
+version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
+checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
[[package]]
name = "bitflags"
@@ -71,21 +72,21 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
-version = "2.6.0"
+version = "2.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
+checksum = "6a65b545ab31d687cff52899d4890855fec459eb6afe0da6417b8a18da87aa29"
[[package]]
name = "cfg-if"
-version = "1.0.0"
+version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9"
[[package]]
name = "clap"
-version = "4.5.20"
+version = "4.5.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8"
+checksum = "1fc0e74a703892159f5ae7d3aac52c8e6c392f5ae5f359c70b5881d60aaac318"
dependencies = [
"clap_builder",
"clap_derive",
@@ -93,9 +94,9 @@ dependencies = [
[[package]]
name = "clap_builder"
-version = "4.5.20"
+version = "4.5.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54"
+checksum = "b3e7f4214277f3c7aa526a59dd3fbe306a370daee1f8b7b8c987069cd8e888a8"
dependencies = [
"anstream",
"anstyle",
@@ -105,9 +106,9 @@ dependencies = [
[[package]]
name = "clap_derive"
-version = "4.5.18"
+version = "4.5.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab"
+checksum = "14cb31bb0a7d536caef2639baa7fad459e15c3144efefa6dbd1c84562c4739f6"
dependencies = [
"heck",
"proc-macro2",
@@ -117,25 +118,26 @@ dependencies = [
[[package]]
name = "clap_lex"
-version = "0.7.2"
+version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97"
+checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675"
[[package]]
name = "colorchoice"
-version = "1.0.2"
+version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0"
+checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
[[package]]
name = "crossterm"
-version = "0.28.1"
+version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6"
+checksum = "d8b9f2e4c67f833b660cdb0a3523065869fb35570177239812ed4c905aeff87b"
dependencies = [
- "bitflags 2.6.0",
+ "bitflags 2.9.2",
"crossterm_winapi",
- "mio 1.0.2",
+ "document-features",
+ "mio",
"parking_lot",
"rustix",
"signal-hook",
@@ -153,44 +155,35 @@ dependencies = [
]
[[package]]
-name = "equivalent"
-version = "1.0.1"
+name = "document-features"
+version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
+checksum = "95249b50c6c185bee49034bcb378a49dc2b5dff0be90ff6616d31d64febab05d"
+dependencies = [
+ "litrs",
+]
+
+[[package]]
+name = "equivalent"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
[[package]]
name = "errno"
-version = "0.3.9"
+version = "0.3.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba"
+checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad"
dependencies = [
"libc",
- "windows-sys 0.52.0",
+ "windows-sys 0.60.2",
]
[[package]]
name = "fastrand"
-version = "2.1.1"
+version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6"
-
-[[package]]
-name = "filetime"
-version = "0.2.25"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586"
-dependencies = [
- "cfg-if",
- "libc",
- "libredox",
- "windows-sys 0.59.0",
-]
-
-[[package]]
-name = "foldhash"
-version = "0.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2"
+checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
[[package]]
name = "fsevent-sys"
@@ -202,10 +195,22 @@ dependencies = [
]
[[package]]
-name = "hashbrown"
-version = "0.15.0"
+name = "getrandom"
+version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb"
+checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "r-efi",
+ "wasi 0.14.2+wasi-0.2.4",
+]
+
+[[package]]
+name = "hashbrown"
+version = "0.15.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
[[package]]
name = "heck"
@@ -213,17 +218,11 @@ version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
-[[package]]
-name = "hermit-abi"
-version = "0.3.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
-
[[package]]
name = "indexmap"
-version = "2.6.0"
+version = "2.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da"
+checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661"
dependencies = [
"equivalent",
"hashbrown",
@@ -231,11 +230,11 @@ dependencies = [
[[package]]
name = "inotify"
-version = "0.9.6"
+version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f8069d3ec154eb856955c1c0fbffefbf5f3c40a104ec912d4797314c1801abff"
+checksum = "f37dccff2791ab604f9babef0ba14fbe0be30bd368dc541e2b08d07c8aa908f3"
dependencies = [
- "bitflags 1.3.2",
+ "bitflags 2.9.2",
"inotify-sys",
"libc",
]
@@ -257,15 +256,15 @@ checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
[[package]]
name = "itoa"
-version = "1.0.11"
+version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
+checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
[[package]]
name = "kqueue"
-version = "1.0.8"
+version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7447f1ca1b7b563588a205fe93dea8df60fd981423a768bc1c0ded35ed147d0c"
+checksum = "eac30106d7dce88daf4a3fcb4879ea939476d5074a9b7ddd0fb97fa4bed5596a"
dependencies = [
"kqueue-sys",
"libc",
@@ -283,32 +282,27 @@ dependencies = [
[[package]]
name = "libc"
-version = "0.2.159"
+version = "0.2.175"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5"
-
-[[package]]
-name = "libredox"
-version = "0.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
-dependencies = [
- "bitflags 2.6.0",
- "libc",
- "redox_syscall",
-]
+checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543"
[[package]]
name = "linux-raw-sys"
-version = "0.4.14"
+version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
+checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12"
+
+[[package]]
+name = "litrs"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f5e54036fe321fd421e10d732f155734c4e4afd610dd556d9a82833ab3ee0bed"
[[package]]
name = "lock_api"
-version = "0.4.12"
+version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
+checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765"
dependencies = [
"autocfg",
"scopeguard",
@@ -316,80 +310,69 @@ dependencies = [
[[package]]
name = "log"
-version = "0.4.22"
+version = "0.4.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
+checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
[[package]]
name = "memchr"
-version = "2.7.4"
+version = "2.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
+checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
[[package]]
name = "mio"
-version = "0.8.11"
+version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c"
+checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c"
dependencies = [
"libc",
"log",
- "wasi",
- "windows-sys 0.48.0",
-]
-
-[[package]]
-name = "mio"
-version = "1.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec"
-dependencies = [
- "hermit-abi",
- "libc",
- "log",
- "wasi",
- "windows-sys 0.52.0",
+ "wasi 0.11.1+wasi-snapshot-preview1",
+ "windows-sys 0.59.0",
]
[[package]]
name = "notify"
-version = "6.1.1"
+version = "8.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6205bd8bb1e454ad2e27422015fb5e4f2bcc7e08fa8f27058670d208324a4d2d"
+checksum = "4d3d07927151ff8575b7087f245456e549fea62edf0ec4e565a5ee50c8402bc3"
dependencies = [
- "bitflags 2.6.0",
- "filetime",
+ "bitflags 2.9.2",
"fsevent-sys",
"inotify",
"kqueue",
"libc",
"log",
- "mio 0.8.11",
+ "mio",
+ "notify-types",
"walkdir",
- "windows-sys 0.48.0",
+ "windows-sys 0.60.2",
]
+[[package]]
+name = "notify-types"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5e0826a989adedc2a244799e823aece04662b66609d96af8dff7ac6df9a8925d"
+
[[package]]
name = "once_cell"
-version = "1.20.2"
+version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
+checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
[[package]]
-name = "os_pipe"
-version = "1.2.1"
+name = "once_cell_polyfill"
+version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5ffd2b0a5634335b135d5728d84c5e0fd726954b87111f7506a61c502280d982"
-dependencies = [
- "libc",
- "windows-sys 0.59.0",
-]
+checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad"
[[package]]
name = "parking_lot"
-version = "0.12.3"
+version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27"
+checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13"
dependencies = [
"lock_api",
"parking_lot_core",
@@ -397,9 +380,9 @@ dependencies = [
[[package]]
name = "parking_lot_core"
-version = "0.9.10"
+version = "0.9.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
+checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5"
dependencies = [
"cfg-if",
"libc",
@@ -410,76 +393,80 @@ dependencies = [
[[package]]
name = "proc-macro2"
-version = "1.0.87"
+version = "1.0.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a"
+checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
-version = "1.0.37"
+version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
+checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
dependencies = [
"proc-macro2",
]
[[package]]
-name = "redox_syscall"
-version = "0.5.7"
+name = "r-efi"
+version = "5.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f"
+checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
+
+[[package]]
+name = "redox_syscall"
+version = "0.5.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77"
dependencies = [
- "bitflags 2.6.0",
+ "bitflags 2.9.2",
]
[[package]]
name = "rustix"
-version = "0.38.37"
+version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811"
+checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8"
dependencies = [
- "bitflags 2.6.0",
+ "bitflags 2.9.2",
"errno",
"libc",
"linux-raw-sys",
- "windows-sys 0.52.0",
+ "windows-sys 0.60.2",
]
[[package]]
name = "rustlings"
-version = "6.3.0"
+version = "6.5.0"
dependencies = [
"anyhow",
"clap",
"crossterm",
- "foldhash",
"notify",
- "os_pipe",
"rustix",
"rustlings-macros",
"serde",
"serde_json",
"tempfile",
- "toml_edit",
+ "toml",
]
[[package]]
name = "rustlings-macros"
-version = "6.3.0"
+version = "6.5.0"
dependencies = [
"quote",
"serde",
- "toml_edit",
+ "toml",
]
[[package]]
name = "ryu"
-version = "1.0.18"
+version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
+checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
[[package]]
name = "same-file"
@@ -498,18 +485,18 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "serde"
-version = "1.0.210"
+version = "1.0.219"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a"
+checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
-version = "1.0.210"
+version = "1.0.219"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f"
+checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
dependencies = [
"proc-macro2",
"quote",
@@ -518,9 +505,9 @@ dependencies = [
[[package]]
name = "serde_json"
-version = "1.0.128"
+version = "1.0.143"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8"
+checksum = "d401abef1d108fbd9cbaebc3e46611f4b1021f714a0597a71f41ee463f5f4a5a"
dependencies = [
"itoa",
"memchr",
@@ -530,18 +517,18 @@ dependencies = [
[[package]]
name = "serde_spanned"
-version = "0.6.8"
+version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1"
+checksum = "40734c41988f7306bb04f0ecf60ec0f3f1caa34290e4e8ea471dcd3346483b83"
dependencies = [
"serde",
]
[[package]]
name = "signal-hook"
-version = "0.3.17"
+version = "0.3.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801"
+checksum = "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2"
dependencies = [
"libc",
"signal-hook-registry",
@@ -554,24 +541,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd"
dependencies = [
"libc",
- "mio 1.0.2",
+ "mio",
"signal-hook",
]
[[package]]
name = "signal-hook-registry"
-version = "1.4.2"
+version = "1.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1"
+checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b"
dependencies = [
"libc",
]
[[package]]
name = "smallvec"
-version = "1.13.2"
+version = "1.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
+checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
[[package]]
name = "strsim"
@@ -581,9 +568,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "syn"
-version = "2.0.79"
+version = "2.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590"
+checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6"
dependencies = [
"proc-macro2",
"quote",
@@ -592,44 +579,61 @@ dependencies = [
[[package]]
name = "tempfile"
-version = "3.13.0"
+version = "3.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b"
+checksum = "15b61f8f20e3a6f7e0649d825294eaf317edce30f82cf6026e7e4cb9222a7d1e"
dependencies = [
- "cfg-if",
"fastrand",
+ "getrandom",
"once_cell",
"rustix",
- "windows-sys 0.59.0",
+ "windows-sys 0.60.2",
]
[[package]]
-name = "toml_datetime"
-version = "0.6.8"
+name = "toml"
+version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41"
-dependencies = [
- "serde",
-]
-
-[[package]]
-name = "toml_edit"
-version = "0.22.22"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5"
+checksum = "75129e1dc5000bfbaa9fee9d1b21f974f9fbad9daec557a521ee6e080825f6e8"
dependencies = [
"indexmap",
"serde",
"serde_spanned",
"toml_datetime",
+ "toml_parser",
+ "toml_writer",
"winnow",
]
[[package]]
-name = "unicode-ident"
-version = "1.0.13"
+name = "toml_datetime"
+version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
+checksum = "bade1c3e902f58d73d3f294cd7f20391c1cb2fbcb643b73566bc773971df91e3"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "toml_parser"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b551886f449aa90d4fe2bdaa9f4a2577ad2dde302c61ecf262d80b116db95c10"
+dependencies = [
+ "winnow",
+]
+
+[[package]]
+name = "toml_writer"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fcc842091f2def52017664b53082ecbbeb5c7731092bad69d2c63050401dfd64"
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
[[package]]
name = "utf8parse"
@@ -649,9 +653,18 @@ dependencies = [
[[package]]
name = "wasi"
-version = "0.11.0+wasi-snapshot-preview1"
+version = "0.11.1+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
+checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
+
+[[package]]
+name = "wasi"
+version = "0.14.2+wasi-0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3"
+dependencies = [
+ "wit-bindgen-rt",
+]
[[package]]
name = "winapi"
@@ -671,11 +684,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-util"
-version = "0.1.9"
+version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
+checksum = "0978bf7171b3d90bac376700cb56d606feb40f251a475a5d6634613564460b22"
dependencies = [
- "windows-sys 0.59.0",
+ "windows-sys 0.60.2",
]
[[package]]
@@ -685,22 +698,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
-name = "windows-sys"
-version = "0.48.0"
+name = "windows-link"
+version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
-dependencies = [
- "windows-targets 0.48.5",
-]
-
-[[package]]
-name = "windows-sys"
-version = "0.52.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
-dependencies = [
- "windows-targets 0.52.6",
-]
+checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
[[package]]
name = "windows-sys"
@@ -712,18 +713,12 @@ dependencies = [
]
[[package]]
-name = "windows-targets"
-version = "0.48.5"
+name = "windows-sys"
+version = "0.60.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
+checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
dependencies = [
- "windows_aarch64_gnullvm 0.48.5",
- "windows_aarch64_msvc 0.48.5",
- "windows_i686_gnu 0.48.5",
- "windows_i686_msvc 0.48.5",
- "windows_x86_64_gnu 0.48.5",
- "windows_x86_64_gnullvm 0.48.5",
- "windows_x86_64_msvc 0.48.5",
+ "windows-targets 0.53.3",
]
[[package]]
@@ -735,7 +730,7 @@ dependencies = [
"windows_aarch64_gnullvm 0.52.6",
"windows_aarch64_msvc 0.52.6",
"windows_i686_gnu 0.52.6",
- "windows_i686_gnullvm",
+ "windows_i686_gnullvm 0.52.6",
"windows_i686_msvc 0.52.6",
"windows_x86_64_gnu 0.52.6",
"windows_x86_64_gnullvm 0.52.6",
@@ -743,10 +738,21 @@ dependencies = [
]
[[package]]
-name = "windows_aarch64_gnullvm"
-version = "0.48.5"
+name = "windows-targets"
+version = "0.53.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
+checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91"
+dependencies = [
+ "windows-link",
+ "windows_aarch64_gnullvm 0.53.0",
+ "windows_aarch64_msvc 0.53.0",
+ "windows_i686_gnu 0.53.0",
+ "windows_i686_gnullvm 0.53.0",
+ "windows_i686_msvc 0.53.0",
+ "windows_x86_64_gnu 0.53.0",
+ "windows_x86_64_gnullvm 0.53.0",
+ "windows_x86_64_msvc 0.53.0",
+]
[[package]]
name = "windows_aarch64_gnullvm"
@@ -755,10 +761,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
-name = "windows_aarch64_msvc"
-version = "0.48.5"
+name = "windows_aarch64_gnullvm"
+version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
+checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764"
[[package]]
name = "windows_aarch64_msvc"
@@ -767,10 +773,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
-name = "windows_i686_gnu"
-version = "0.48.5"
+name = "windows_aarch64_msvc"
+version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
+checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c"
[[package]]
name = "windows_i686_gnu"
@@ -778,6 +784,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
+[[package]]
+name = "windows_i686_gnu"
+version = "0.53.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3"
+
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
@@ -785,10 +797,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
-name = "windows_i686_msvc"
-version = "0.48.5"
+name = "windows_i686_gnullvm"
+version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
+checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11"
[[package]]
name = "windows_i686_msvc"
@@ -797,10 +809,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
-name = "windows_x86_64_gnu"
-version = "0.48.5"
+name = "windows_i686_msvc"
+version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
+checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d"
[[package]]
name = "windows_x86_64_gnu"
@@ -809,10 +821,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
-name = "windows_x86_64_gnullvm"
-version = "0.48.5"
+name = "windows_x86_64_gnu"
+version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
+checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba"
[[package]]
name = "windows_x86_64_gnullvm"
@@ -821,10 +833,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
-name = "windows_x86_64_msvc"
-version = "0.48.5"
+name = "windows_x86_64_gnullvm"
+version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
+checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57"
[[package]]
name = "windows_x86_64_msvc"
@@ -833,10 +845,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
-name = "winnow"
-version = "0.6.20"
+name = "windows_x86_64_msvc"
+version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b"
+checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
+
+[[package]]
+name = "winnow"
+version = "0.7.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f3edebf492c8125044983378ecb5766203ad3b4c2f7a922bd7dd207f6d443e95"
+
+[[package]]
+name = "wit-bindgen-rt"
+version = "0.39.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
dependencies = [
- "memchr",
+ "bitflags 2.9.2",
]
diff --git a/Cargo.toml b/Cargo.toml
index eb22cfee..4469b281 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,12 +1,11 @@
[workspace]
-resolver = "2"
exclude = [
"tests/test_exercises",
"dev",
]
[workspace.package]
-version = "6.3.0"
+version = "6.5.0"
authors = [
"Mo Bitar ", # https://github.com/mo8it
"Liv ", # https://github.com/shadows-withal
@@ -15,12 +14,12 @@ authors = [
]
repository = "https://github.com/rust-lang/rustlings"
license = "MIT"
-edition = "2021" # On Update: Update the edition of the `rustfmt` command that checks the solutions.
-rust-version = "1.80"
+edition = "2024" # On Update: Update the edition of `rustfmt` in `dev check` and `CARGO_TOML` in `dev new`.
+rust-version = "1.88"
[workspace.dependencies]
-serde = { version = "1.0.210", features = ["derive"] }
-toml_edit = { version = "0.22.22", default-features = false, features = ["parse", "serde"] }
+serde = { version = "1.0", features = ["derive"] }
+toml = { version = "0.9", default-features = false, features = ["std", "parse", "serde"] }
[package]
name = "rustlings"
@@ -46,22 +45,20 @@ include = [
]
[dependencies]
-anyhow = "1.0.89"
-clap = { version = "4.5.20", features = ["derive"] }
-crossterm = { version = "0.28.1", default-features = false, features = ["windows", "events"] }
-foldhash = "0.1.3"
-notify = { version = "6.1.1", default-features = false, features = ["macos_fsevent"] }
-os_pipe = "1.2.1"
-rustlings-macros = { path = "rustlings-macros", version = "=6.3.0" }
-serde_json = "1.0.128"
+anyhow = "1.0"
+clap = { version = "4.5", features = ["derive"] }
+crossterm = { version = "0.29", default-features = false, features = ["windows", "events"] }
+notify = "8.0"
+rustlings-macros = { path = "rustlings-macros", version = "=6.5.0" }
+serde_json = "1.0"
serde.workspace = true
-toml_edit.workspace = true
+toml.workspace = true
[target.'cfg(not(windows))'.dependencies]
-rustix = { version = "0.38.37", default-features = false, features = ["std", "stdio", "termios"] }
+rustix = { version = "1.0", default-features = false, features = ["std", "stdio", "termios"] }
[dev-dependencies]
-tempfile = "3.13.0"
+tempfile = "3.21"
[profile.release]
panic = "abort"
@@ -71,6 +68,7 @@ panic = "abort"
[package.metadata.release]
pre-release-hook = ["./release-hook.sh"]
+pre-release-commit-message = "Release 🎉"
[workspace.lints.rust]
unsafe_code = "forbid"
@@ -84,8 +82,6 @@ infinite_loop = "deny"
mem_forget = "deny"
dbg_macro = "warn"
todo = "warn"
-# TODO: Remove after the following fix is released: https://github.com/rust-lang/rust-clippy/pull/13102
-needless_option_as_deref = "allow"
[lints]
workspace = true
diff --git a/README.md b/README.md
index c8148801..0ae6265d 100644
--- a/README.md
+++ b/README.md
@@ -1,173 +1,7 @@
-
+# [Rustlings](https://rustlings.rust-lang.org) 🦀
-# Rustlings 🦀❤️
+Small exercises to get you used to reading and writing [Rust](https://www.rust-lang.org) code - _Recommended in parallel to reading [the official Rust book](https://doc.rust-lang.org/book) 📚️_
-
+Visit the **website** for a demo, info about setup and more:
-Greetings and welcome to Rustlings.
-This project contains small exercises to get you used to reading and writing Rust code.
-This includes reading and responding to compiler messages!
-
-It is recommended to do the Rustlings exercises in parallel to reading [the official Rust book](https://doc.rust-lang.org/book/), the most comprehensive resource for learning Rust 📚️
-
-[Rust By Example](https://doc.rust-lang.org/rust-by-example/) is another recommended resource that you might find helpful.
-It contains code examples and exercises similar to Rustlings, but online.
-
-## Getting Started
-
-### Installing Rust
-
-Before installing Rustlings, you need to have the **latest version of Rust** installed.
-Visit [www.rust-lang.org/tools/install](https://www.rust-lang.org/tools/install) for further instructions on installing Rust.
-This will also install _Cargo_, Rust's package/project manager.
-
-> 🐧 If you're on Linux, make sure you've installed `gcc` (for a linker).
->
-> Deb: `sudo apt install gcc`.
-> Dnf: `sudo dnf install gcc`.
-
-> 🍎 If you're on MacOS, make sure you've installed Xcode and its developer tools by running `xcode-select --install`.
-
-### Installing Rustlings
-
-The following command will download and compile Rustlings:
-
-```bash
-cargo install rustlings
-```
-
-
-If the installation fails… (click to expand)
-
-- Make sure you have the latest Rust version by running `rustup update`
-- Try adding the `--locked` flag: `cargo install rustlings --locked`
-- Otherwise, please [report the issue](https://github.com/rust-lang/rustlings/issues/new)
-
-
-
-> [!CAUTION]
-> Don't try to clone the repository to do the exercises! `rust-analyzer` won't work in that case. Please follow the instructions above instead.
->
->
-> Why?
->
->The intended way to run Rustlings is to install the binary and run `rustlings init` as described in the installation/initialization sections. This generates a `Cargo.toml` (different than what you see in the repository) that includes each exercise as a separate binary target which is enough for `rust-analyzer` to work.
->
->If you just clone the repository and try to run and edit the exercises directly, the language server will not work.
->
->
-
-### Initialization
-
-After installing Rustlings, run the following command to initialize the `rustlings/` directory:
-
-```bash
-rustlings init
-```
-
-
-If the command rustlings can't be found… (click to expand)
-
-You are probably using Linux and installed Rust using your package manager.
-
-Cargo installs binaries to the directory `~/.cargo/bin`.
-Sadly, package managers often don't add `~/.cargo/bin` to your `PATH` environment variable.
-
-The solution is to …
-
-- either add `~/.cargo/bin` manually to `PATH`
-- or to uninstall Rust from the package manager and install it using the official way with `rustup`: https://www.rust-lang.org/tools/install
-
-
-
-Now, go into the newly initialized directory and launch Rustlings for further instructions on getting started with the exercises:
-
-```bash
-cd rustlings/
-rustlings
-```
-
-## Working environment
-
-### Editor
-
-Our general recommendation is [VS Code](https://code.visualstudio.com/) with the [rust-analyzer plugin](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer).
-But any editor that supports [rust-analyzer](https://rust-analyzer.github.io/) should be enough for working on the exercises.
-
-### Terminal
-
-While working with Rustlings, please use a modern terminal for the best user experience.
-The default terminal on Linux and Mac should be sufficient.
-On Windows, we recommend the [Windows Terminal](https://aka.ms/terminal).
-
-## Doing exercises
-
-The exercises are sorted by topic and can be found in the subdirectory `exercises/`.
-For every topic, there is an additional `README.md` file with some resources to get you started on the topic.
-We highly recommend that you have a look at them before you start 📚️
-
-Most exercises contain an error that keeps them from compiling, and it's up to you to fix it!
-Some exercises contain tests that need to pass for the exercise to be done ✅
-
-Search for `TODO` and `todo!()` to find out what you need to change.
-Ask for hints by entering `h` in the _watch mode_ 💡
-
-### Watch Mode
-
-After [initialization](#initialization), Rustlings can be launched by simply running the command `rustlings`.
-
-This will start the _watch mode_ which walks you through the exercises in a predefined order (what we think is best for newcomers).
-It will rerun the current exercise automatically every time you change the exercise's file in the `exercises/` directory.
-
-
-If detecting file changes in the exercises/ directory fails… (click to expand)
-
-> You can add the **`--manual-run`** flag (`rustlings --manual-run`) to manually rerun the current exercise by entering `r` in the watch mode.
->
-> Please [report the issue](https://github.com/rust-lang/rustlings/issues/new) with some information about your operating system and whether you run Rustlings in a container or virtual machine (e.g. WSL).
-
-
-
-### Exercise List
-
-In the [watch mode](#watch-mode) (after launching `rustlings`), you can enter `l` to open the interactive exercise list.
-
-The list allows you to…
-
-- See the status of all exercises (done or pending)
-- `c`: Continue at another exercise (temporarily skip some exercises or go back to a previous one)
-- `r`: Reset status and file of an exercise (you need to _reload/reopen_ its file in your editor afterwards)
-
-See the footer of the list for all possible keys.
-
-## Continuing On
-
-Once you've completed Rustlings, put your new knowledge to good use!
-Continue practicing your Rust skills by building your own projects, contributing to Rustlings, or finding other open-source projects to contribute to.
-
-## Third-Party Exercises
-
-Third-party exercises are a set of exercises maintained by the community.
-You can use the same `rustlings` program that you installed with `cargo install rustlings` to run them:
-
-- [日本語版 Rustlings](https://github.com/sotanengel/rustlings-jp):A Japanese translation of the Rustlings exercises.
-
-Do you want to create your own set of Rustlings exercises to focus on some specific topic?
-Or do you want to translate the original Rustlings exercises?
-Then follow the the guide about [third-party exercises](https://github.com/rust-lang/rustlings/blob/main/THIRD_PARTY_EXERCISES.md)!
-
-## Uninstalling Rustlings
-
-If you want to remove Rustlings from your system, run the following command:
-
-```bash
-cargo uninstall rustlings
-```
-
-## Contributing
-
-See [CONTRIBUTING.md](https://github.com/rust-lang/rustlings/blob/main/CONTRIBUTING.md) 🔗
-
-## Contributors ✨
-
-Thanks to [all the wonderful contributors](https://github.com/rust-lang/rustlings/graphs/contributors) 🎉
+## ➡️ [rustlings.rust-lang.org](https://rustlings.rust-lang.org) ⬅️
diff --git a/THIRD_PARTY_EXERCISES.md b/THIRD_PARTY_EXERCISES.md
deleted file mode 100644
index 62646c5b..00000000
--- a/THIRD_PARTY_EXERCISES.md
+++ /dev/null
@@ -1,53 +0,0 @@
-# Third-Party Exercises
-
-The support of Rustlings for third-party exercises allows you to create your own set of Rustlings exercises to focus on some specific topic.
-You could also offer a translation of the original Rustlings exercises as third-party exercises.
-
-## Getting started
-
-To create third-party exercises, install Rustlings and run `rustlings dev new PROJECT_NAME`.
-This command will, similar to `cargo new PROJECT_NAME`, create a template directory called `PROJECT_NAME` with all what you need to get started.
-
-Read the comments in the generated `info.toml` file to understand its format.
-It allows you to set a custom welcome and final message and specify the metadata of every exercise.
-
-## Create an exercise
-
-Here is an example of the metadata of one file:
-
-```toml
-[[exercises]]
-name = "intro1"
-hint = """
-To finish this exercise, you need to …
-This link might help you …"""
-```
-
-After entering this in `info.toml`, create the file `intro1.rs` in the `exercises/` directory.
-The exercise needs to contain a `main` function, but it can be empty.
-Adding tests is recommended.
-Look at the official Rustlings exercises for inspiration.
-
-You can optionally add a solution file `intro1.rs` to the `solutions/` directory.
-
-Now, run `rustlings dev check`.
-It will tell you about any issues with your exercises.
-For example, it will tell you to run `rustlings dev update` to update the `Cargo.toml` file to include the new exercise `intro1`.
-
-`rustlings dev check` will also run your solutions (if you have any) to make sure that they run successfully.
-
-That's it!
-You finished your first exercise 🎉
-
-## Publish
-
-Now, add more exercises and publish them as a Git repository.
-
-Users just have to clone that repository and run `rustlings` in it to start working on your set of exercises just like the official ones.
-
-One difference to the official exercises is that the solution files will not be hidden until the user finishes an exercise.
-But you can trust the users to not look at the solution too early 😉
-
-## Share
-
-After publishing your set of exercises, open an issue or a pull request in the official Rustlings repository to link to your project in the README 😃
diff --git a/build.rs b/build.rs
new file mode 100644
index 00000000..56878641
--- /dev/null
+++ b/build.rs
@@ -0,0 +1,5 @@
+fn main() {
+ // Fix building from source on Windows because it can't handle file links.
+ #[cfg(windows)]
+ let _ = std::fs::copy("dev/Cargo.toml", "dev-Cargo.toml");
+}
diff --git a/clippy.toml b/clippy.toml
index 2a981849..89b0a886 100644
--- a/clippy.toml
+++ b/clippy.toml
@@ -1,18 +1,11 @@
disallowed-types = [
- # Inefficient. Use `.queue(…)` instead.
- "crossterm::style::Stylize",
- "crossterm::style::styled_content::StyledContent",
+ { path = "crossterm::style::Stylize", reason = "inefficient, use `.queue(…)` instead" },
+ { path = "crossterm::style::styled_content::StyledContent", reason = "inefficient, use `.queue(…)` instead" },
]
disallowed-methods = [
- # We use `foldhash` instead of the default hasher.
- "std::collections::HashSet::new",
- "std::collections::HashSet::with_capacity",
- # Inefficient. Use `.queue(…)` instead.
- "crossterm::style::style",
- # Use `thread::Builder::spawn` instead and handle the error.
- "std::thread::spawn",
- "std::thread::Scope::spawn",
- # Return `ExitCode` instead.
- "std::process::exit",
+ { path = "crossterm::style::style", reason = "inefficient, use `.queue(…)` instead" },
+ { path = "std::thread::spawn", replacement = "std::thread::Builder::spawn", reason = "handle the error" },
+ { path = "std::thread::Scope::spawn", replacement = "std::thread::Builder::spawn", reason = "handle the error" },
+ { path = "std::process::exit", replacement = "std::process::ExitCode" },
]
diff --git a/dev/Cargo.toml b/dev/Cargo.toml
index 29a557a0..4f725b70 100644
--- a/dev/Cargo.toml
+++ b/dev/Cargo.toml
@@ -1,4 +1,4 @@
-# Don't edit the `bin` list manually! It is updated by `cargo run -- dev update`. This comment line will be stripped in `rustlings init`.
+# Don't edit the `bin` list manually! It is updated by `cargo dev update`. This comment line will be stripped in `rustlings init`.
bin = [
{ name = "intro1", path = "../exercises/00_intro/intro1.rs" },
{ name = "intro1_sol", path = "../solutions/00_intro/intro1.rs" },
@@ -192,7 +192,7 @@ bin = [
[package]
name = "exercises"
-edition = "2021"
+edition = "2024"
# Don't publish the exercises on crates.io!
publish = false
diff --git a/exercises/01_variables/README.md b/exercises/01_variables/README.md
index 7964ff29..5ba2efca 100644
--- a/exercises/01_variables/README.md
+++ b/exercises/01_variables/README.md
@@ -1,7 +1,7 @@
# Variables
In Rust, variables are immutable by default.
-When a variable is immutable, once a value is bound to a name, you can’t change that value.
+When a variable is immutable, once a value is bound to a name, you can't change that value.
You can make them mutable by adding `mut` in front of the variable name.
## Further information
diff --git a/exercises/01_variables/variables5.rs b/exercises/01_variables/variables5.rs
index 49db8e9e..cf5620da 100644
--- a/exercises/01_variables/variables5.rs
+++ b/exercises/01_variables/variables5.rs
@@ -1,6 +1,6 @@
fn main() {
let number = "T-H-R-E-E"; // Don't change this line
- println!("Spell a number: {}", number);
+ println!("Spell a number: {number}");
// TODO: Fix the compiler error by changing the line below without renaming the variable.
number = 3;
diff --git a/exercises/03_if/if2.rs b/exercises/03_if/if2.rs
index 10037f26..ca8493cc 100644
--- a/exercises/03_if/if2.rs
+++ b/exercises/03_if/if2.rs
@@ -19,7 +19,7 @@ mod tests {
#[test]
fn yummy_food() {
- // This means that calling `picky_eater` with the argument "food" should return "Yummy!".
+ // This means that calling `picky_eater` with the argument "strawberry" should return "Yummy!".
assert_eq!(picky_eater("strawberry"), "Yummy!");
}
diff --git a/exercises/05_vecs/vecs2.rs b/exercises/05_vecs/vecs2.rs
index a9be2580..0c996266 100644
--- a/exercises/05_vecs/vecs2.rs
+++ b/exercises/05_vecs/vecs2.rs
@@ -9,26 +9,6 @@ fn vec_loop(input: &[i32]) -> Vec {
output
}
-fn vec_map_example(input: &[i32]) -> Vec {
- // An example of collecting a vector after mapping.
- // We map each element of the `input` slice to its value plus 1.
- // If the input is `[1, 2, 3]`, the output is `[2, 3, 4]`.
- input.iter().map(|element| element + 1).collect()
-}
-
-fn vec_map(input: &[i32]) -> Vec {
- // TODO: Here, we also want to multiply each element in the `input` slice
- // by 2, but with iterator mapping instead of manually pushing into an empty
- // vector.
- // See the example in the function `vec_map_example` above.
- input
- .iter()
- .map(|element| {
- // ???
- })
- .collect()
-}
-
fn main() {
// You can optionally experiment here.
}
@@ -43,18 +23,4 @@ mod tests {
let ans = vec_loop(&input);
assert_eq!(ans, [4, 8, 12, 16, 20]);
}
-
- #[test]
- fn test_vec_map_example() {
- let input = [1, 2, 3];
- let ans = vec_map_example(&input);
- assert_eq!(ans, [2, 3, 4]);
- }
-
- #[test]
- fn test_vec_map() {
- let input = [2, 4, 6, 8, 10];
- let ans = vec_map(&input);
- assert_eq!(ans, [4, 8, 12, 16, 20]);
- }
}
diff --git a/exercises/08_enums/README.md b/exercises/08_enums/README.md
index 30d4d91d..b05cb422 100644
--- a/exercises/08_enums/README.md
+++ b/exercises/08_enums/README.md
@@ -1,10 +1,10 @@
# Enums
Rust allows you to define types called "enums" which enumerate possible values.
-Enums are a feature in many languages, but their capabilities differ in each language. Rust’s enums are most similar to algebraic data types in functional languages, such as F#, OCaml, and Haskell.
+Enums are a feature in many languages, but their capabilities differ in each language. Rust's enums are most similar to algebraic data types in functional languages, such as F#, OCaml, and Haskell.
Useful in combination with enums is Rust's "pattern matching" facility, which makes it easy to run different code for different values of an enumeration.
## Further information
- [Enums](https://doc.rust-lang.org/book/ch06-00-enums.html)
-- [Pattern syntax](https://doc.rust-lang.org/book/ch18-03-pattern-syntax.html)
+- [Pattern syntax](https://doc.rust-lang.org/book/ch19-03-pattern-syntax.html)
diff --git a/exercises/09_strings/strings3.rs b/exercises/09_strings/strings3.rs
index 39fce18c..f5e45b0f 100644
--- a/exercises/09_strings/strings3.rs
+++ b/exercises/09_strings/strings3.rs
@@ -23,6 +23,7 @@ mod tests {
assert_eq!(trim_me("Hello! "), "Hello!");
assert_eq!(trim_me(" What's up!"), "What's up!");
assert_eq!(trim_me(" Hola! "), "Hola!");
+ assert_eq!(trim_me("Hi!"), "Hi!");
}
#[test]
diff --git a/exercises/11_hashmaps/hashmaps3.rs b/exercises/11_hashmaps/hashmaps3.rs
index 7e9584d1..5b390ab9 100644
--- a/exercises/11_hashmaps/hashmaps3.rs
+++ b/exercises/11_hashmaps/hashmaps3.rs
@@ -17,7 +17,7 @@ struct TeamScores {
fn build_scores_table(results: &str) -> HashMap<&str, TeamScores> {
// The name of the team is the key and its associated struct is the value.
- let mut scores = HashMap::new();
+ let mut scores = HashMap::<&str, TeamScores>::new();
for line in results.lines() {
let mut split_iterator = line.split(',');
diff --git a/exercises/12_options/options1.rs b/exercises/12_options/options1.rs
index 99648078..d0c412a8 100644
--- a/exercises/12_options/options1.rs
+++ b/exercises/12_options/options1.rs
@@ -1,8 +1,8 @@
-// This function returns how much icecream there is left in the fridge.
+// This function returns how much ice cream there is left in the fridge.
// If it's before 22:00 (24-hour system), then 5 scoops are left. At 22:00,
-// someone eats it all, so no icecream is left (value 0). Return `None` if
+// someone eats it all, so no ice cream is left (value 0). Return `None` if
// `hour_of_day` is higher than 23.
-fn maybe_icecream(hour_of_day: u16) -> Option {
+fn maybe_ice_cream(hour_of_day: u16) -> Option {
// TODO: Complete the function body.
}
@@ -18,19 +18,19 @@ mod tests {
fn raw_value() {
// TODO: Fix this test. How do you get the value contained in the
// Option?
- let icecreams = maybe_icecream(12);
+ let ice_creams = maybe_ice_cream(12);
- assert_eq!(icecreams, 5); // Don't change this line.
+ assert_eq!(ice_creams, 5); // Don't change this line.
}
#[test]
- fn check_icecream() {
- assert_eq!(maybe_icecream(0), Some(5));
- assert_eq!(maybe_icecream(9), Some(5));
- assert_eq!(maybe_icecream(18), Some(5));
- assert_eq!(maybe_icecream(22), Some(0));
- assert_eq!(maybe_icecream(23), Some(0));
- assert_eq!(maybe_icecream(24), None);
- assert_eq!(maybe_icecream(25), None);
+ fn check_ice_cream() {
+ assert_eq!(maybe_ice_cream(0), Some(5));
+ assert_eq!(maybe_ice_cream(9), Some(5));
+ assert_eq!(maybe_ice_cream(18), Some(5));
+ assert_eq!(maybe_ice_cream(22), Some(0));
+ assert_eq!(maybe_ice_cream(23), Some(0));
+ assert_eq!(maybe_ice_cream(24), None);
+ assert_eq!(maybe_ice_cream(25), None);
}
}
diff --git a/exercises/12_options/options3.rs b/exercises/12_options/options3.rs
index 4cedb512..c97b1d3c 100644
--- a/exercises/12_options/options3.rs
+++ b/exercises/12_options/options3.rs
@@ -9,7 +9,7 @@ fn main() {
// TODO: Fix the compiler error by adding something to this match statement.
match optional_point {
- Some(p) => println!("Co-ordinates are {},{}", p.x, p.y),
+ Some(p) => println!("Coordinates are {},{}", p.x, p.y),
_ => panic!("No match!"),
}
diff --git a/exercises/13_error_handling/README.md b/exercises/13_error_handling/README.md
index 3b21f2b7..9b6674bc 100644
--- a/exercises/13_error_handling/README.md
+++ b/exercises/13_error_handling/README.md
@@ -1,8 +1,8 @@
# Error handling
-Most errors aren’t serious enough to require the program to stop entirely.
-Sometimes, when a function fails, it’s for a reason that you can easily interpret and respond to.
-For example, if you try to open a file and that operation fails because the file doesn’t exist, you might want to create the file instead of terminating the process.
+Most errors aren't serious enough to require the program to stop entirely.
+Sometimes, when a function fails, it's for a reason that you can easily interpret and respond to.
+For example, if you try to open a file and that operation fails because the file doesn't exist, you might want to create the file instead of terminating the process.
## Further information
diff --git a/exercises/13_error_handling/errors4.rs b/exercises/13_error_handling/errors4.rs
index ba01e54b..144fce7b 100644
--- a/exercises/13_error_handling/errors4.rs
+++ b/exercises/13_error_handling/errors4.rs
@@ -10,6 +10,7 @@ struct PositiveNonzeroInteger(u64);
impl PositiveNonzeroInteger {
fn new(value: i64) -> Result {
// TODO: This function shouldn't always return an `Ok`.
+ // Read the tests below to clarify what should be returned.
Ok(Self(value as u64))
}
}
diff --git a/exercises/13_error_handling/errors5.rs b/exercises/13_error_handling/errors5.rs
index 57218351..125779b8 100644
--- a/exercises/13_error_handling/errors5.rs
+++ b/exercises/13_error_handling/errors5.rs
@@ -6,7 +6,7 @@
//
// 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` where
+// trait. To do so, the `Box` is declared as of type `Box` where
// `Trait` is the trait the compiler looks for on any value used in that
// context. For this exercise, that context is the potential errors which
// can be returned in a `Result`.
diff --git a/exercises/18_iterators/iterators3.rs b/exercises/18_iterators/iterators3.rs
index 6b1eca17..dce09055 100644
--- a/exercises/18_iterators/iterators3.rs
+++ b/exercises/18_iterators/iterators3.rs
@@ -39,6 +39,8 @@ mod tests {
#[test]
fn test_success() {
assert_eq!(divide(81, 9), Ok(9));
+ assert_eq!(divide(81, -1), Ok(-81));
+ assert_eq!(divide(i64::MIN, i64::MIN), Ok(1));
}
#[test]
diff --git a/exercises/20_threads/threads1.rs b/exercises/20_threads/threads1.rs
index 01f9ff44..dbc64b16 100644
--- a/exercises/20_threads/threads1.rs
+++ b/exercises/20_threads/threads1.rs
@@ -1,5 +1,5 @@
-// This program spawns multiple threads that each run for at least 250ms, and
-// each thread returns how much time they took to complete. The program should
+// This program spawns multiple threads that each runs for at least 250ms, and
+// each thread returns how much time it took to complete. The program should
// wait until all the spawned threads have finished and should collect their
// return values into a vector.
diff --git a/exercises/21_macros/README.md b/exercises/21_macros/README.md
index 337816d6..de7fb7ba 100644
--- a/exercises/21_macros/README.md
+++ b/exercises/21_macros/README.md
@@ -10,5 +10,6 @@ of exercises to Rustlings, but is all about learning to write Macros.
## Further information
-- [Macros](https://doc.rust-lang.org/book/ch19-06-macros.html)
+- [The Rust Book - Macros](https://doc.rust-lang.org/book/ch20-05-macros.html)
- [The Little Book of Rust Macros](https://veykril.github.io/tlborm/)
+- [Rust by Example - macro_rules!](https://doc.rust-lang.org/rust-by-example/macros.html)
diff --git a/exercises/22_clippy/clippy3.rs b/exercises/22_clippy/clippy3.rs
index 4f788349..7a3cb390 100644
--- a/exercises/22_clippy/clippy3.rs
+++ b/exercises/22_clippy/clippy3.rs
@@ -4,9 +4,11 @@
#[rustfmt::skip]
#[allow(unused_variables, unused_assignments)]
fn main() {
- let my_option: Option<()> = None;
+ let my_option: Option<&str> = None;
+ // Assume that you don't know the value of `my_option`.
+ // In the case of `Some`, we want to print its value.
if my_option.is_none() {
- println!("{:?}", my_option.unwrap());
+ println!("{}", my_option.unwrap());
}
let my_arr = &[
diff --git a/exercises/README.md b/exercises/README.md
index 237f2f1e..1df5cc37 100644
--- a/exercises/README.md
+++ b/exercises/README.md
@@ -22,6 +22,6 @@
| iterators | §13.2-4 |
| smart_pointers | §15, §16.3 |
| threads | §16.1-3 |
-| macros | §19.5 |
-| clippy | §21.4 |
+| macros | §20.5 |
+| clippy | Appendix D |
| conversions | n/a |
diff --git a/oranda.json b/oranda.json
deleted file mode 100644
index ecc490b2..00000000
--- a/oranda.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "project": {
- "homepage": "https://rustlings.cool",
- "repository": "https://github.com/rust-lang/rustlings"
- },
- "marketing": {
- "analytics": {
- "plausible": {
- "domain": "rustlings.cool"
- }
- }
- }
-}
diff --git a/release-hook.sh b/release-hook.sh
index d5954ca8..49349337 100755
--- a/release-hook.sh
+++ b/release-hook.sh
@@ -9,5 +9,8 @@ cargo upgrades
# Similar to CI
cargo clippy -- --deny warnings
cargo fmt --all --check
-cargo test --workspace --all-targets
-cargo run -- dev check --require-solutions
+cargo test --workspace
+cargo dev check --require-solutions
+
+# MSRV
+cargo +1.88 dev check --require-solutions
diff --git a/rustlings-macros/Cargo.toml b/rustlings-macros/Cargo.toml
index 3ed56a18..5df648b2 100644
--- a/rustlings-macros/Cargo.toml
+++ b/rustlings-macros/Cargo.toml
@@ -16,9 +16,9 @@ include = [
proc-macro = true
[dependencies]
-quote = "1.0.37"
+quote = "1.0"
serde.workspace = true
-toml_edit.workspace = true
+toml.workspace = true
[lints]
workspace = true
diff --git a/rustlings-macros/info.toml b/rustlings-macros/info.toml
index c1342d68..ca3ecf1f 100644
--- a/rustlings-macros/info.toml
+++ b/rustlings-macros/info.toml
@@ -318,16 +318,7 @@ of the Rust book to learn more."""
name = "vecs2"
dir = "05_vecs"
hint = """
-In the first function, we create an empty vector and want to push new elements
-to it.
-
-In the second function, we map the values of the input and collect them into
-a vector.
-
-After you've completed both functions, decide for yourself which approach you
-like better.
-
-What do you think is the more commonly used pattern under Rust developers?"""
+Use the `.push()` method on the vector to push new elements to it."""
# MOVE SEMANTICS
@@ -575,12 +566,8 @@ https://doc.rust-lang.org/book/ch08-03-hash-maps.html#only-inserting-a-value-if-
name = "hashmaps3"
dir = "11_hashmaps"
hint = """
-Hint 1: Use the `entry()` and `or_insert()` (or `or_insert_with()`) methods of
- `HashMap` to insert the default value of `TeamScores` if a team doesn't
- exist in the table yet.
-
-Learn more in The Book:
-https://doc.rust-lang.org/book/ch08-03-hash-maps.html#only-inserting-a-value-if-the-key-has-no-value
+Hint 1: Use the `entry()` and `or_default()` methods of `HashMap` to insert the
+ default value of `TeamScores` if a team doesn't exist in the table yet.
Hint 2: If there is already an entry for a given key, the value returned by
`entry()` can be updated based on the existing value.
@@ -768,7 +755,7 @@ Notice how the trait takes ownership of `self` and returns `Self`.
Although the signature of `append_bar` in the trait takes `self` as argument,
the implementation can take `mut self` instead. This is possible because the
-the value is owned anyway."""
+value is owned anyway."""
[[exercises]]
name = "traits3"
diff --git a/rustlings-macros/src/lib.rs b/rustlings-macros/src/lib.rs
index 6c6067bc..b20c6f1d 100644
--- a/rustlings-macros/src/lib.rs
+++ b/rustlings-macros/src/lib.rs
@@ -16,7 +16,7 @@ struct InfoFile {
#[proc_macro]
pub fn include_files(_: TokenStream) -> TokenStream {
let info_file = include_str!("../info.toml");
- let exercises = toml_edit::de::from_str::(info_file)
+ let exercises = toml::de::from_str::(info_file)
.expect("Failed to parse `info.toml`")
.exercises;
diff --git a/solutions/01_variables/variables5.rs b/solutions/01_variables/variables5.rs
index 9057754c..0ea39030 100644
--- a/solutions/01_variables/variables5.rs
+++ b/solutions/01_variables/variables5.rs
@@ -1,6 +1,6 @@
fn main() {
let number = "T-H-R-E-E";
- println!("Spell a number: {}", number);
+ println!("Spell a number: {number}");
// Using variable shadowing
// https://doc.rust-lang.org/book/ch03-01-variables-and-mutability.html#shadowing
diff --git a/solutions/03_if/if1.rs b/solutions/03_if/if1.rs
index 079c6715..8512a60f 100644
--- a/solutions/03_if/if1.rs
+++ b/solutions/03_if/if1.rs
@@ -1,9 +1,5 @@
fn bigger(a: i32, b: i32) -> i32 {
- if a > b {
- a
- } else {
- b
- }
+ if a > b { a } else { b }
}
fn main() {
diff --git a/solutions/05_vecs/vecs2.rs b/solutions/05_vecs/vecs2.rs
index 87f7625a..aae71038 100644
--- a/solutions/05_vecs/vecs2.rs
+++ b/solutions/05_vecs/vecs2.rs
@@ -8,22 +8,6 @@ fn vec_loop(input: &[i32]) -> Vec {
output
}
-fn vec_map_example(input: &[i32]) -> Vec {
- // An example of collecting a vector after mapping.
- // We map each element of the `input` slice to its value plus 1.
- // If the input is `[1, 2, 3]`, the output is `[2, 3, 4]`.
- input.iter().map(|element| element + 1).collect()
-}
-
-fn vec_map(input: &[i32]) -> Vec {
- // We will dive deeper into iterators, but for now, this is all what you
- // had to do!
- // Advanced note: This method is more efficient because it automatically
- // preallocates enough capacity. This can be done manually in `vec_loop`
- // using `Vec::with_capacity(input.len())` instead of `Vec::new()`.
- input.iter().map(|element| 2 * element).collect()
-}
-
fn main() {
// You can optionally experiment here.
}
@@ -38,18 +22,4 @@ mod tests {
let ans = vec_loop(&input);
assert_eq!(ans, [4, 8, 12, 16, 20]);
}
-
- #[test]
- fn test_vec_map_example() {
- let input = [1, 2, 3];
- let ans = vec_map_example(&input);
- assert_eq!(ans, [2, 3, 4]);
- }
-
- #[test]
- fn test_vec_map() {
- let input = [2, 4, 6, 8, 10];
- let ans = vec_map(&input);
- assert_eq!(ans, [4, 8, 12, 16, 20]);
- }
}
diff --git a/solutions/06_move_semantics/move_semantics4.rs b/solutions/06_move_semantics/move_semantics4.rs
index 64fdd9db..1a39d4fc 100644
--- a/solutions/06_move_semantics/move_semantics4.rs
+++ b/solutions/06_move_semantics/move_semantics4.rs
@@ -4,8 +4,6 @@ fn main() {
#[cfg(test)]
mod tests {
- // TODO: Fix the compiler errors only by reordering the lines in the test.
- // Don't add, change or remove any line.
#[test]
fn move_semantics4() {
let mut x = Vec::new();
diff --git a/solutions/09_strings/strings3.rs b/solutions/09_strings/strings3.rs
index a478e62a..ee6b56af 100644
--- a/solutions/09_strings/strings3.rs
+++ b/solutions/09_strings/strings3.rs
@@ -26,6 +26,7 @@ mod tests {
assert_eq!(trim_me("Hello! "), "Hello!");
assert_eq!(trim_me(" What's up!"), "What's up!");
assert_eq!(trim_me(" Hola! "), "Hola!");
+ assert_eq!(trim_me("Hi!"), "Hi!");
}
#[test]
diff --git a/solutions/11_hashmaps/hashmaps3.rs b/solutions/11_hashmaps/hashmaps3.rs
index 8a5d30b6..485bf830 100644
--- a/solutions/11_hashmaps/hashmaps3.rs
+++ b/solutions/11_hashmaps/hashmaps3.rs
@@ -17,7 +17,7 @@ struct TeamScores {
fn build_scores_table(results: &str) -> HashMap<&str, TeamScores> {
// The name of the team is the key and its associated struct is the value.
- let mut scores = HashMap::new();
+ let mut scores = HashMap::<&str, TeamScores>::new();
for line in results.lines() {
let mut split_iterator = line.split(',');
@@ -28,17 +28,13 @@ fn build_scores_table(results: &str) -> HashMap<&str, TeamScores> {
let team_2_score: u8 = split_iterator.next().unwrap().parse().unwrap();
// Insert the default with zeros if a team doesn't exist yet.
- let team_1 = scores
- .entry(team_1_name)
- .or_insert_with(TeamScores::default);
+ let team_1 = scores.entry(team_1_name).or_default();
// Update the values.
team_1.goals_scored += team_1_score;
team_1.goals_conceded += team_2_score;
// Similarly for the second team.
- let team_2 = scores
- .entry(team_2_name)
- .or_insert_with(TeamScores::default);
+ let team_2 = scores.entry(team_2_name).or_default();
team_2.goals_scored += team_2_score;
team_2.goals_conceded += team_1_score;
}
@@ -64,9 +60,11 @@ England,Spain,1,0";
fn build_scores() {
let scores = build_scores_table(RESULTS);
- assert!(["England", "France", "Germany", "Italy", "Poland", "Spain"]
- .into_iter()
- .all(|team_name| scores.contains_key(team_name)));
+ assert!(
+ ["England", "France", "Germany", "Italy", "Poland", "Spain"]
+ .into_iter()
+ .all(|team_name| scores.contains_key(team_name))
+ );
}
#[test]
diff --git a/solutions/12_options/options3.rs b/solutions/12_options/options3.rs
index 0081eeb2..c918f711 100644
--- a/solutions/12_options/options3.rs
+++ b/solutions/12_options/options3.rs
@@ -10,7 +10,7 @@ fn main() {
// Solution 1: Matching over the `Option` (not `&Option`) but without moving
// out of the `Some` variant.
match optional_point {
- Some(ref p) => println!("Co-ordinates are {},{}", p.x, p.y),
+ Some(ref p) => println!("Coordinates are {},{}", p.x, p.y),
// ^^^ added
_ => panic!("No match!"),
}
@@ -18,7 +18,8 @@ fn main() {
// Solution 2: Matching over a reference (`&Option`) by added `&` before
// `optional_point`.
match &optional_point {
- Some(p) => println!("Co-ordinates are {},{}", p.x, p.y),
+ //^ added
+ Some(p) => println!("Coordinates are {},{}", p.x, p.y),
_ => panic!("No match!"),
}
diff --git a/solutions/13_error_handling/errors2.rs b/solutions/13_error_handling/errors2.rs
index 0597c8c9..f0e144e7 100644
--- a/solutions/13_error_handling/errors2.rs
+++ b/solutions/13_error_handling/errors2.rs
@@ -16,7 +16,7 @@
use std::num::ParseIntError;
-#[allow(unused_variables)]
+#[allow(unused_variables, clippy::question_mark)]
fn total_cost(item_quantity: &str) -> Result {
let processing_fee = 1;
let cost_per_item = 5;
diff --git a/solutions/13_error_handling/errors6.rs b/solutions/13_error_handling/errors6.rs
index 86793619..ce18073a 100644
--- a/solutions/13_error_handling/errors6.rs
+++ b/solutions/13_error_handling/errors6.rs
@@ -29,6 +29,21 @@ impl ParsePosNonzeroError {
}
}
+// As an alternative solution, implementing the `From` trait allows for the
+// automatic conversion from a `ParseIntError` into a `ParsePosNonzeroError`
+// using the `?` operator, without the need to call `map_err`.
+//
+// ```
+// let x: i64 = s.parse()?;
+// ```
+//
+// Traits like `From` will be dealt with in later exercises.
+impl From for ParsePosNonzeroError {
+ fn from(err: ParseIntError) -> Self {
+ ParsePosNonzeroError::ParseInt(err)
+ }
+}
+
#[derive(PartialEq, Debug)]
struct PositiveNonzeroInteger(u64);
diff --git a/solutions/16_lifetimes/lifetimes1.rs b/solutions/16_lifetimes/lifetimes1.rs
index ca7b688d..4f56834f 100644
--- a/solutions/16_lifetimes/lifetimes1.rs
+++ b/solutions/16_lifetimes/lifetimes1.rs
@@ -5,11 +5,7 @@
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
// ^^^^ ^^ ^^ ^^
- if x.len() > y.len() {
- x
- } else {
- y
- }
+ if x.len() > y.len() { x } else { y }
}
fn main() {
diff --git a/solutions/16_lifetimes/lifetimes2.rs b/solutions/16_lifetimes/lifetimes2.rs
index b0f2ef1f..3ca49093 100644
--- a/solutions/16_lifetimes/lifetimes2.rs
+++ b/solutions/16_lifetimes/lifetimes2.rs
@@ -1,9 +1,5 @@
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
- if x.len() > y.len() {
- x
- } else {
- y
- }
+ if x.len() > y.len() { x } else { y }
}
fn main() {
diff --git a/solutions/18_iterators/iterators3.rs b/solutions/18_iterators/iterators3.rs
index 11aa1ec8..1d5d67f2 100644
--- a/solutions/18_iterators/iterators3.rs
+++ b/solutions/18_iterators/iterators3.rs
@@ -52,6 +52,8 @@ mod tests {
#[test]
fn test_success() {
assert_eq!(divide(81, 9), Ok(9));
+ assert_eq!(divide(81, -1), Ok(-81));
+ assert_eq!(divide(i64::MIN, i64::MIN), Ok(1));
}
#[test]
diff --git a/solutions/19_smart_pointers/rc1.rs b/solutions/19_smart_pointers/rc1.rs
index c0a41abf..edf40ebe 100644
--- a/solutions/19_smart_pointers/rc1.rs
+++ b/solutions/19_smart_pointers/rc1.rs
@@ -63,12 +63,10 @@ mod tests {
println!("reference count = {}", Rc::strong_count(&sun)); // 7 references
saturn.details();
- // TODO
let uranus = Planet::Uranus(Rc::clone(&sun));
println!("reference count = {}", Rc::strong_count(&sun)); // 8 references
uranus.details();
- // TODO
let neptune = Planet::Neptune(Rc::clone(&sun));
println!("reference count = {}", Rc::strong_count(&sun)); // 9 references
neptune.details();
diff --git a/solutions/20_threads/threads1.rs b/solutions/20_threads/threads1.rs
index 7f3dd29a..1fc5bc9c 100644
--- a/solutions/20_threads/threads1.rs
+++ b/solutions/20_threads/threads1.rs
@@ -1,5 +1,5 @@
-// This program spawns multiple threads that each run for at least 250ms, and
-// each thread returns how much time they took to complete. The program should
+// This program spawns multiple threads that each runs for at least 250ms, and
+// each thread returns how much time it took to complete. The program should
// wait until all the spawned threads have finished and should collect their
// return values into a vector.
diff --git a/solutions/22_clippy/clippy3.rs b/solutions/22_clippy/clippy3.rs
index 811d1847..81f381e0 100644
--- a/solutions/22_clippy/clippy3.rs
+++ b/solutions/22_clippy/clippy3.rs
@@ -3,11 +3,11 @@ use std::mem;
#[rustfmt::skip]
#[allow(unused_variables, unused_assignments)]
fn main() {
- let my_option: Option<()> = None;
+ let my_option: Option<&str> = None;
// `unwrap` of an `Option` after checking if it is `None` will panic.
// Use `if-let` instead.
if let Some(value) = my_option {
- println!("{value:?}");
+ println!("{value}");
}
// A comma was missing.
@@ -15,7 +15,7 @@ fn main() {
-1, -2, -3,
-4, -5, -6,
];
- println!("My array! Here it is: {:?}", my_arr);
+ println!("My array! Here it is: {my_arr:?}");
let mut my_empty_vec = vec![1, 2, 3, 4, 5];
// `resize` mutates a vector instead of returning a new one.
@@ -27,5 +27,5 @@ fn main() {
let mut value_b = 66;
// Use `mem::swap` to correctly swap two values.
mem::swap(&mut value_a, &mut value_b);
- println!("value a: {}; value b: {}", value_a, value_b);
+ println!("value a: {value_a}; value b: {value_b}");
}
diff --git a/solutions/quizzes/quiz2.rs b/solutions/quizzes/quiz2.rs
index 58cbe4e2..8b073b18 100644
--- a/solutions/quizzes/quiz2.rs
+++ b/solutions/quizzes/quiz2.rs
@@ -62,8 +62,8 @@ mod tests {
// Import `transformer`.
use super::my_module::transformer;
- use super::my_module::transformer_iter;
use super::Command;
+ use super::my_module::transformer_iter;
#[test]
fn it_works() {
diff --git a/src/app_state.rs b/src/app_state.rs
index 4007fbc3..d654d042 100644
--- a/src/app_state.rs
+++ b/src/app_state.rs
@@ -1,10 +1,11 @@
-use anyhow::{bail, Context, Error, Result};
-use crossterm::{cursor, terminal, QueueableCommand};
+use anyhow::{Context, Error, Result, bail};
+use crossterm::{QueueableCommand, cursor, terminal};
use std::{
+ collections::HashSet,
env,
fs::{File, OpenOptions},
io::{Read, Seek, StdoutLock, Write},
- path::{Path, MAIN_SEPARATOR_STR},
+ path::{MAIN_SEPARATOR_STR, Path},
process::{Command, Stdio},
sync::{
atomic::{AtomicUsize, Ordering::Relaxed},
@@ -16,7 +17,6 @@ use std::{
use crate::{
clear_terminal,
cmd::CmdRunner,
- collections::hash_set_with_capacity,
embedded::EMBEDDED_FILES,
exercise::{Exercise, RunnableExercise},
info_file::ExerciseInfo,
@@ -60,8 +60,7 @@ pub struct AppState {
file_buf: Vec,
official_exercises: bool,
cmd_runner: CmdRunner,
- // Running in VS Code.
- vs_code: bool,
+ emit_file_links: bool,
}
impl AppState {
@@ -146,7 +145,7 @@ impl AppState {
break 'block StateFileStatus::NotRead;
}
- let mut done_exercises = hash_set_with_capacity(exercises.len());
+ let mut done_exercises = HashSet::with_capacity(exercises.len());
for done_exercise_name in lines {
if done_exercise_name.is_empty() {
@@ -181,7 +180,8 @@ impl AppState {
file_buf,
official_exercises: !Path::new("info.toml").exists(),
cmd_runner,
- vs_code: env::var_os("TERM_PROGRAM").is_some_and(|v| v == "vscode"),
+ // VS Code has its own file link handling
+ emit_file_links: env::var_os("TERM_PROGRAM").is_none_or(|v| v != "vscode"),
};
Ok((slf, state_file_status))
@@ -218,8 +218,8 @@ impl AppState {
}
#[inline]
- pub fn vs_code(&self) -> bool {
- self.vs_code
+ pub fn emit_file_links(&self) -> bool {
+ self.emit_file_links
}
// Write the state file.
@@ -315,7 +315,7 @@ impl AppState {
}
// Official exercises: Dump the original file from the binary.
- // Third-party exercises: Reset the exercise file with `git stash`.
+ // Community exercises: Reset the exercise file with `git stash`.
fn reset(&self, exercise_ind: usize, path: &str) -> Result<()> {
if self.official_exercises {
return EMBEDDED_FILES
@@ -385,7 +385,7 @@ impl AppState {
}
/// Official exercises: Dump the solution file from the binary and return its path.
- /// Third-party exercises: Check if a solution file exists and return its path in that case.
+ /// Community exercises: Check if a solution file exists and return its path in that case.
pub fn current_solution_path(&self) -> Result