Compare commits

...

35 commits

Author SHA1 Message Date
Mo Bitar
8b4562e102
Merge pull request from ubitux/no-todo
Remove TODO from 2 solutions
2025-04-03 19:36:06 +02:00
mo8it
63d8986f2a Update links 2025-04-03 18:22:55 +02:00
mo8it
ecaecc2f76 Update deps 2025-04-03 17:58:36 +02:00
Mo Bitar
78194b4441
Merge pull request from cassian-goode/patch-1
Fix typo - errors5.rs
2025-04-03 17:52:57 +02:00
Mo Bitar
44699e9b1b
Merge pull request from Hunter-Plus/patch-1
Update README.md
2025-04-03 17:52:15 +02:00
Hunter Z
9978c17d5f
Update README.md
Update the URL while add more reference.
2025-03-31 12:58:06 +08:00
cassian-goode
3cc7e0377c
Fix typo - errors5.rs
Minor typo correction in exercise instructions
2025-03-25 09:24:49 -04:00
Clément Bœsch
d2abc359cc Remove TODO from 2 solutions 2025-03-17 18:36:13 +01:00
mo8it
7c0d269279 Update README 2025-03-14 11:42:16 +01:00
mo8it
8db85946af Update deps 2025-03-14 11:33:56 +01:00
mo8it
7019f4d178 Update pipeline 2025-03-14 11:33:56 +01:00
Mo Bitar
ae444eb3da
Merge pull request from peterneave/main
Use consistent apostrophes in markdown files
2025-03-02 17:30:29 +01:00
Peter Neave
425c9821e0 Use consistent apostrophes in markdown files 2025-02-28 11:46:39 +11:00
mo8it
46c6fb2c82 Update deps 2025-02-25 11:21:19 +01:00
mo8it
374c3874af Apply 2024 edition formatting to solutions 2025-02-21 13:08:34 +01:00
mo8it
1eb6c1e469 Update the edition of the solution format checker 2025-02-21 13:06:11 +01:00
mo8it
06af3ffc99 Bump MSRV in release hook 2025-02-18 20:17:27 +01:00
mo8it
65dc019fa6 Fix new Clippy error in solution 2025-02-18 20:15:50 +01:00
mo8it
a56ccb6f4f Fix new Clippy lint 2025-02-18 20:12:23 +01:00
mo8it
d9872f2615 Upgrade to edition 2024 2025-02-18 20:10:52 +01:00
mo8it
298be671b9 Update deps 2025-02-18 20:03:49 +01:00
mo8it
fbfd4f25e7 Disable following symlinks in the watcher 2025-01-16 10:41:48 +01:00
mo8it
d12735a573 Update deps 2025-01-16 10:41:17 +01:00
mo8it
1aec7c1152 Fix Windows CI 2025-01-01 22:07:41 +01:00
mo8it
0b55809bb9 Fix building from source on Windows 2025-01-01 22:01:39 +01:00
mo8it
bde6f7470c Co-ordinates -> Coordinates 2024-12-28 16:46:24 +01:00
mo8it
53ec59ed95 Rename translations 2024-12-28 16:41:43 +01:00
mo8it
ed1ee38923 Link to simplified Chinese translation 2024-12-28 16:40:07 +01:00
Mo
26cf4989a2
Merge pull request from JoelMarcey/if2-comment-fix
Fix argument comment in test of if2.rs
2024-12-13 19:48:16 +01:00
Joel Marcey
6e60f441e9
Fix argument comment in test of if2.rs 2024-12-13 10:44:21 -08:00
mo8it
d07de879a7 Update deps 2024-12-11 00:12:49 +01:00
Mo
dd0634c483
Merge pull request from mnshdw/mnshdw/feedback-errors6
errors6: Add alternative solution using From trait
2024-11-14 14:49:57 +01:00
Antoine Dupuis
fc0cd8f0f8 Switch comment style to // 2024-11-14 09:14:40 +01:00
Antoine Dupuis
d5cae8ff59 Add alternative solution using From trait 2024-11-13 23:51:09 +01:00
mo8it
38016cb2d6 clippy3: Make the intent more clear 2024-11-13 16:06:41 +01:00
47 changed files with 345 additions and 255 deletions

View file

@ -22,22 +22,22 @@ jobs:
- 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
- name: rustlings dev check
run: cargo run -- dev check --require-solutions

View file

@ -1,3 +1,10 @@
## Unreleased
### Changed
- Upgrade to Rust edition 2024
- Raise the minimum supported Rust version to `1.85`
<a name="6.4.0"></a>
## 6.4.0 (2024-11-11)

251
Cargo.lock generated
View file

@ -1,6 +1,6 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
version = 4
[[package]]
name = "anstream"
@ -43,19 +43,20 @@ dependencies = [
[[package]]
name = "anstyle-wincon"
version = "3.0.6"
version = "3.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125"
checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e"
dependencies = [
"anstyle",
"once_cell",
"windows-sys 0.59.0",
]
[[package]]
name = "anyhow"
version = "1.0.93"
version = "1.0.97"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775"
checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f"
[[package]]
name = "autocfg"
@ -71,9 +72,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
version = "2.6.0"
version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"
[[package]]
name = "cfg-if"
@ -83,9 +84,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
version = "4.5.20"
version = "4.5.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8"
checksum = "d8aa86934b44c19c50f87cc2790e19f54f7a67aedb64101c2e1a2e5ecfb73944"
dependencies = [
"clap_builder",
"clap_derive",
@ -93,9 +94,9 @@ dependencies = [
[[package]]
name = "clap_builder"
version = "4.5.20"
version = "4.5.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54"
checksum = "2414dbb2dd0695280da6ea9261e327479e9d37b0630f6b53ba2a11c60c679fd9"
dependencies = [
"anstream",
"anstyle",
@ -105,9 +106,9 @@ dependencies = [
[[package]]
name = "clap_derive"
version = "4.5.18"
version = "4.5.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab"
checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7"
dependencies = [
"heck",
"proc-macro2",
@ -117,9 +118,9 @@ dependencies = [
[[package]]
name = "clap_lex"
version = "0.7.2"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97"
checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6"
[[package]]
name = "colorchoice"
@ -133,11 +134,11 @@ version = "0.28.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.9.0",
"crossterm_winapi",
"mio",
"parking_lot",
"rustix",
"rustix 0.38.44",
"signal-hook",
"signal-hook-mio",
"winapi",
@ -154,25 +155,25 @@ dependencies = [
[[package]]
name = "equivalent"
version = "1.0.1"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
[[package]]
name = "errno"
version = "0.3.9"
version = "0.3.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba"
checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d"
dependencies = [
"libc",
"windows-sys 0.52.0",
"windows-sys 0.59.0",
]
[[package]]
name = "fastrand"
version = "2.2.0"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4"
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
[[package]]
name = "filetime"
@ -196,10 +197,22 @@ dependencies = [
]
[[package]]
name = "hashbrown"
version = "0.15.1"
name = "getrandom"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3"
checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0"
dependencies = [
"cfg-if",
"libc",
"r-efi",
"wasi 0.14.2+wasi-0.2.4",
]
[[package]]
name = "hashbrown"
version = "0.15.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
[[package]]
name = "heck"
@ -207,17 +220,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.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da"
checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058"
dependencies = [
"equivalent",
"hashbrown",
@ -225,11 +232,11 @@ dependencies = [
[[package]]
name = "inotify"
version = "0.10.2"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fdd168d97690d0b8c412d6b6c10360277f4d7ee495c5d0d5d5fe0854923255cc"
checksum = "f37dccff2791ab604f9babef0ba14fbe0be30bd368dc541e2b08d07c8aa908f3"
dependencies = [
"bitflags 1.3.2",
"bitflags 2.9.0",
"inotify-sys",
"libc",
]
@ -243,15 +250,6 @@ dependencies = [
"libc",
]
[[package]]
name = "instant"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222"
dependencies = [
"cfg-if",
]
[[package]]
name = "is_terminal_polyfill"
version = "1.70.1"
@ -260,9 +258,9 @@ 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"
@ -286,9 +284,9 @@ dependencies = [
[[package]]
name = "libc"
version = "0.2.162"
version = "0.2.171"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398"
checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
[[package]]
name = "libredox"
@ -296,16 +294,22 @@ version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.9.0",
"libc",
"redox_syscall",
]
[[package]]
name = "linux-raw-sys"
version = "0.4.14"
version = "0.4.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
[[package]]
name = "linux-raw-sys"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe7db12097d22ec582439daf8618b8fdd1a7bef6270e9af3b1ebcd30893cf413"
[[package]]
name = "lock_api"
@ -319,9 +323,9 @@ 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"
@ -331,24 +335,23 @@ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]]
name = "mio"
version = "1.0.2"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec"
checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd"
dependencies = [
"hermit-abi",
"libc",
"log",
"wasi",
"wasi 0.11.0+wasi-snapshot-preview1",
"windows-sys 0.52.0",
]
[[package]]
name = "notify"
version = "7.0.0"
version = "8.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c533b4c39709f9ba5005d8002048266593c1cfaf3c5f0739d5b8ab0c6c504009"
checksum = "2fee8403b3d66ac7b26aee6e40a897d85dc5ce26f44da36b8b73e987cc52e943"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.9.0",
"filetime",
"fsevent-sys",
"inotify",
@ -358,23 +361,20 @@ dependencies = [
"mio",
"notify-types",
"walkdir",
"windows-sys 0.52.0",
"windows-sys 0.59.0",
]
[[package]]
name = "notify-types"
version = "1.0.0"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7393c226621f817964ffb3dc5704f9509e107a8b024b489cc2c1b217378785df"
dependencies = [
"instant",
]
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"
@ -411,42 +411,61 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.89"
version = "1.0.94"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e"
checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84"
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.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f"
checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5"
[[package]]
name = "redox_syscall"
version = "0.5.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.9.0",
]
[[package]]
name = "rustix"
version = "0.38.40"
version = "0.38.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99e4ea3e1cdc4b559b8e5650f9c8e5998e3e5c1343b4eaf034565f32318d63c0"
checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154"
dependencies = [
"bitflags 2.6.0",
"bitflags 2.9.0",
"errno",
"libc",
"linux-raw-sys",
"windows-sys 0.52.0",
"linux-raw-sys 0.4.15",
"windows-sys 0.59.0",
]
[[package]]
name = "rustix"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d97817398dd4bb2e6da002002db259209759911da105da92bec29ccb12cf58bf"
dependencies = [
"bitflags 2.9.0",
"errno",
"libc",
"linux-raw-sys 0.9.3",
"windows-sys 0.59.0",
]
[[package]]
@ -458,7 +477,7 @@ dependencies = [
"crossterm",
"notify",
"os_pipe",
"rustix",
"rustix 1.0.5",
"rustlings-macros",
"serde",
"serde_json",
@ -477,9 +496,9 @@ dependencies = [
[[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 +517,18 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "serde"
version = "1.0.214"
version = "1.0.219"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5"
checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.214"
version = "1.0.219"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766"
checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
dependencies = [
"proc-macro2",
"quote",
@ -518,9 +537,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.132"
version = "1.0.140"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03"
checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373"
dependencies = [
"itoa",
"memchr",
@ -569,9 +588,9 @@ dependencies = [
[[package]]
name = "smallvec"
version = "1.13.2"
version = "1.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd"
[[package]]
name = "strsim"
@ -581,9 +600,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "syn"
version = "2.0.87"
version = "2.0.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d"
checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
dependencies = [
"proc-macro2",
"quote",
@ -592,14 +611,14 @@ dependencies = [
[[package]]
name = "tempfile"
version = "3.14.0"
version = "3.19.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c"
checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf"
dependencies = [
"cfg-if",
"fastrand",
"getrandom",
"once_cell",
"rustix",
"rustix 1.0.5",
"windows-sys 0.59.0",
]
@ -614,9 +633,9 @@ dependencies = [
[[package]]
name = "toml_edit"
version = "0.22.22"
version = "0.22.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5"
checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474"
dependencies = [
"indexmap",
"serde",
@ -627,9 +646,9 @@ dependencies = [
[[package]]
name = "unicode-ident"
version = "1.0.13"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
[[package]]
name = "utf8parse"
@ -653,6 +672,15 @@ version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[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"
version = "0.3.9"
@ -768,9 +796,18 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "winnow"
version = "0.6.20"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b"
checksum = "0e97b544156e9bebe1a0ffbc03484fc1ffe3100cbce3ffb17eac35f7cdd7ab36"
dependencies = [
"memchr",
]
[[package]]
name = "wit-bindgen-rt"
version = "0.39.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
dependencies = [
"bitflags 2.9.0",
]

View file

@ -15,12 +15,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.85"
[workspace.dependencies]
serde = { version = "1.0.214", features = ["derive"] }
toml_edit = { version = "0.22.22", default-features = false, features = ["parse", "serde"] }
serde = { version = "1.0", features = ["derive"] }
toml_edit = { version = "0.22", default-features = false, features = ["parse", "serde"] }
[package]
name = "rustlings"
@ -46,21 +46,21 @@ include = [
]
[dependencies]
anyhow = "1.0.93"
clap = { version = "4.5.20", features = ["derive"] }
crossterm = { version = "0.28.1", default-features = false, features = ["windows", "events"] }
notify = "7.0.0"
os_pipe = "1.2.1"
anyhow = "1.0"
clap = { version = "4.5", features = ["derive"] }
crossterm = { version = "0.28", default-features = false, features = ["windows", "events"] }
notify = "8.0"
os_pipe = "1.2"
rustlings-macros = { path = "rustlings-macros", version = "=6.4.0" }
serde_json = "1.0.132"
serde_json = "1.0"
serde.workspace = true
toml_edit.workspace = true
[target.'cfg(not(windows))'.dependencies]
rustix = { version = "0.38.38", default-features = false, features = ["std", "stdio", "termios"] }
rustix = { version = "1.0", default-features = false, features = ["std", "stdio", "termios"] }
[dev-dependencies]
tempfile = "3.14.0"
tempfile = "3.19"
[profile.release]
panic = "abort"

View file

@ -21,12 +21,13 @@ Before installing Rustlings, you need to have the **latest version of Rust** ins
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).
> 🐧 If you are on Linux, make sure you have installed `gcc` (for a linker).
>
> Deb: `sudo apt install gcc`.
> Dnf: `sudo dnf install gcc`.
> 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`.
> 🍎 If you are on MacOS, make sure you have installed Xcode and its developer tools by running `xcode-select --install`.
### Installing Rustlings
@ -102,7 +103,7 @@ 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`.
After the [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.
@ -137,7 +138,8 @@ If you need any help while doing the exercises and the builtin-hints aren't help
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.
- 🇯🇵 [Japanese Rustlings](https://github.com/sotanengel/rustlings-jp)A Japanese translation of the Rustlings exercises.
- 🇨🇳 [Simplified Chinese Rustlings](https://github.com/SandmeyerX/rustlings-zh-cn): A simplified Chinese 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?
@ -160,6 +162,4 @@ cargo uninstall rustlings
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) 🎉
Thanks to [all the wonderful contributors](https://github.com/rust-lang/rustlings/graphs/contributors) ✨

5
build.rs Normal file
View file

@ -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");
}

View file

@ -192,7 +192,7 @@ bin = [
[package]
name = "exercises"
edition = "2021"
edition = "2024"
# Don't publish the exercises on crates.io!
publish = false

View file

@ -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 cant 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

View file

@ -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!");
}

View file

@ -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. Rusts 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)

View file

@ -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!"),
}

View file

@ -1,8 +1,8 @@
# Error handling
Most errors arent serious enough to require the program to stop entirely.
Sometimes, when a function fails, its 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 doesnt 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

View file

@ -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<dyn Trait>` where
// trait. To do so, the `Box` is declared as of type `Box<dyn Trait>` 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`.

View file

@ -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)

View file

@ -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 = &[

View file

@ -13,4 +13,4 @@ cargo test --workspace --all-targets
cargo run -- dev check --require-solutions
# MSRV
cargo +1.80 run -- dev check --require-solutions
cargo +1.85 run -- dev check --require-solutions

View file

@ -16,7 +16,7 @@ include = [
proc-macro = true
[dependencies]
quote = "1.0.37"
quote = "1.0"
serde.workspace = true
toml_edit.workspace = true

View file

@ -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() {

View file

@ -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();

View file

@ -60,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]

View file

@ -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!"),
}

View file

@ -16,7 +16,7 @@
use std::num::ParseIntError;
#[allow(unused_variables)]
#[allow(unused_variables, clippy::question_mark)]
fn total_cost(item_quantity: &str) -> Result<i32, ParseIntError> {
let processing_fee = 1;
let cost_per_item = 5;

View file

@ -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<ParseIntError> for ParsePosNonzeroError {
fn from(err: ParseIntError) -> Self {
ParsePosNonzeroError::ParseInt(err)
}
}
#[derive(PartialEq, Debug)]
struct PositiveNonzeroInteger(u64);

View file

@ -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() {

View file

@ -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() {

View file

@ -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();

View file

@ -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.

View file

@ -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() {

View file

@ -1,11 +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},
@ -427,32 +427,34 @@ impl AppState {
let next_exercise_ind = &next_exercise_ind;
let slf = &self;
thread::Builder::new()
.spawn_scoped(s, move || loop {
let exercise_ind = next_exercise_ind.fetch_add(1, Relaxed);
let Some(exercise) = slf.exercises.get(exercise_ind) else {
// No more exercises.
break;
};
.spawn_scoped(s, move || {
loop {
let exercise_ind = next_exercise_ind.fetch_add(1, Relaxed);
let Some(exercise) = slf.exercises.get(exercise_ind) else {
// No more exercises.
break;
};
if exercise_progress_sender
.send((exercise_ind, CheckProgress::Checking))
.is_err()
{
break;
};
if exercise_progress_sender
.send((exercise_ind, CheckProgress::Checking))
.is_err()
{
break;
};
let success = exercise.run_exercise(None, &slf.cmd_runner);
let progress = match success {
Ok(true) => CheckProgress::Done,
Ok(false) => CheckProgress::Pending,
Err(_) => CheckProgress::None,
};
let success = exercise.run_exercise(None, &slf.cmd_runner);
let progress = match success {
Ok(true) => CheckProgress::Done,
Ok(false) => CheckProgress::Pending,
Err(_) => CheckProgress::None,
};
if exercise_progress_sender
.send((exercise_ind, progress))
.is_err()
{
break;
if exercise_progress_sender
.send((exercise_ind, progress))
.is_err()
{
break;
}
}
})
.context("Failed to spawn a thread to check all exercises")?;

View file

@ -74,13 +74,13 @@ pub fn updated_cargo_toml(
let (bins_start_ind, bins_end_ind) = bins_start_end_ind(current_cargo_toml)?;
let mut updated_cargo_toml = Vec::with_capacity(BINS_BUFFER_CAPACITY);
updated_cargo_toml.extend_from_slice(current_cargo_toml[..bins_start_ind].as_bytes());
updated_cargo_toml.extend_from_slice(&current_cargo_toml.as_bytes()[..bins_start_ind]);
append_bins(
&mut updated_cargo_toml,
exercise_infos,
exercise_path_prefix,
);
updated_cargo_toml.extend_from_slice(current_cargo_toml[bins_end_ind..].as_bytes());
updated_cargo_toml.extend_from_slice(&current_cargo_toml.as_bytes()[bins_end_ind..]);
Ok(updated_cargo_toml)
}

View file

@ -1,4 +1,4 @@
use anyhow::{bail, Context, Result};
use anyhow::{Context, Result, bail};
use serde::Deserialize;
use std::{
io::Read,

View file

@ -1,4 +1,4 @@
use anyhow::{bail, Context, Result};
use anyhow::{Context, Result, bail};
use clap::Subcommand;
use std::path::PathBuf;

View file

@ -1,8 +1,8 @@
use anyhow::{anyhow, bail, Context, Error, Result};
use anyhow::{Context, Error, Result, anyhow, bail};
use std::{
cmp::Ordering,
collections::HashSet,
fs::{self, read_dir, OpenOptions},
fs::{self, OpenOptions, read_dir},
io::{self, Read, Write},
path::{Path, PathBuf},
process::{Command, Stdio},
@ -10,11 +10,11 @@ use std::{
};
use crate::{
cargo_toml::{append_bins, bins_start_end_ind, BINS_BUFFER_CAPACITY},
cmd::CmdRunner,
exercise::{RunnableExercise, OUTPUT_CAPACITY},
info_file::{ExerciseInfo, InfoFile},
CURRENT_FORMAT_VERSION,
cargo_toml::{BINS_BUFFER_CAPACITY, append_bins, bins_start_end_ind},
cmd::CmdRunner,
exercise::{OUTPUT_CAPACITY, RunnableExercise},
info_file::{ExerciseInfo, InfoFile},
};
const MAX_N_EXERCISES: usize = 999;
@ -42,10 +42,14 @@ fn check_cargo_toml(
if old_bins != new_bins {
if cfg!(debug_assertions) {
bail!("The file `dev/Cargo.toml` is outdated. Run `cargo run -- dev update` to update it. Then run `cargo run -- dev check` again");
bail!(
"The file `dev/Cargo.toml` is outdated. Run `cargo run -- dev update` to update it. Then run `cargo run -- dev check` again"
);
}
bail!("The file `Cargo.toml` is outdated. Run `rustlings dev update` to update it. Then run `rustlings dev check` again");
bail!(
"The file `Cargo.toml` is outdated. Run `rustlings dev update` to update it. Then run `rustlings dev check` again"
);
}
Ok(())
@ -63,7 +67,9 @@ fn check_info_file_exercises(info_file: &InfoFile) -> Result<HashSet<PathBuf>> {
bail!("Found an empty exercise name in `info.toml`");
}
if name.len() > MAX_EXERCISE_NAME_LEN {
bail!("The length of the exercise name `{name}` is bigger than the maximum {MAX_EXERCISE_NAME_LEN}");
bail!(
"The length of the exercise name `{name}` is bigger than the maximum {MAX_EXERCISE_NAME_LEN}"
);
}
if let Some(c) = forbidden_char(name) {
bail!("Char `{c}` in the exercise name `{name}` is not allowed");
@ -79,7 +85,9 @@ fn check_info_file_exercises(info_file: &InfoFile) -> Result<HashSet<PathBuf>> {
}
if exercise_info.hint.trim_ascii().is_empty() {
bail!("The exercise `{name}` has an empty hint. Please provide a hint or at least tell the user why a hint isn't needed for this exercise");
bail!(
"The exercise `{name}` has an empty hint. Please provide a hint or at least tell the user why a hint isn't needed for this exercise"
);
}
if !names.insert(name) {
@ -96,20 +104,28 @@ fn check_info_file_exercises(info_file: &InfoFile) -> Result<HashSet<PathBuf>> {
.with_context(|| format!("Failed to read the file {path}"))?;
if !file_buf.contains("fn main()") {
bail!("The `main` function is missing in the file `{path}`.\nCreate at least an empty `main` function to avoid language server errors");
bail!(
"The `main` function is missing in the file `{path}`.\nCreate at least an empty `main` function to avoid language server errors"
);
}
if !file_buf.contains("// TODO") {
bail!("Didn't find any `// TODO` comment in the file `{path}`.\nYou need to have at least one such comment to guide the user.");
bail!(
"Didn't find any `// TODO` comment in the file `{path}`.\nYou need to have at least one such comment to guide the user."
);
}
let contains_tests = file_buf.contains("#[test]\n");
if exercise_info.test {
if !contains_tests {
bail!("The file `{path}` doesn't contain any tests. If you don't want to add tests to this exercise, set `test = false` for this exercise in the `info.toml` file");
bail!(
"The file `{path}` doesn't contain any tests. If you don't want to add tests to this exercise, set `test = false` for this exercise in the `info.toml` file"
);
}
} else if contains_tests {
bail!("The file `{path}` contains tests annotated with `#[test]` but the exercise `{name}` has `test = false` in the `info.toml` file");
bail!(
"The file `{path}` contains tests annotated with `#[test]` but the exercise `{name}` has `test = false` in the `info.toml` file"
);
}
file_buf.clear();
@ -125,7 +141,10 @@ fn check_info_file_exercises(info_file: &InfoFile) -> Result<HashSet<PathBuf>> {
// Only one level of directory nesting is allowed.
fn check_unexpected_files(dir: &str, allowed_rust_files: &HashSet<PathBuf>) -> Result<()> {
let unexpected_file = |path: &Path| {
anyhow!("Found the file `{}`. Only `README.md` and Rust files related to an exercise in `info.toml` are allowed in the `{dir}` directory", path.display())
anyhow!(
"Found the file `{}`. Only `README.md` and Rust files related to an exercise in `info.toml` are allowed in the `{dir}` directory",
path.display()
)
};
for entry in read_dir(dir).with_context(|| format!("Failed to open the `{dir}` directory"))? {
@ -154,7 +173,10 @@ fn check_unexpected_files(dir: &str, allowed_rust_files: &HashSet<PathBuf>) -> R
let path = entry.path();
if !entry.file_type().unwrap().is_file() {
bail!("Found `{}` but expected only files. Only one level of exercise nesting is allowed", path.display());
bail!(
"Found `{}` but expected only files. Only one level of exercise nesting is allowed",
path.display()
);
}
let file_name = path.file_name().unwrap();
@ -224,8 +246,12 @@ fn check_exercises_unsolved(
fn check_exercises(info_file: &'static InfoFile, cmd_runner: &'static CmdRunner) -> Result<()> {
match info_file.format_version.cmp(&CURRENT_FORMAT_VERSION) {
Ordering::Less => bail!("`format_version` < {CURRENT_FORMAT_VERSION} (supported version)\nPlease migrate to the latest format version"),
Ordering::Greater => bail!("`format_version` > {CURRENT_FORMAT_VERSION} (supported version)\nTry updating the Rustlings program"),
Ordering::Less => bail!(
"`format_version` < {CURRENT_FORMAT_VERSION} (supported version)\nPlease migrate to the latest format version"
),
Ordering::Greater => bail!(
"`format_version` > {CURRENT_FORMAT_VERSION} (supported version)\nTry updating the Rustlings program"
),
Ordering::Equal => (),
}
@ -287,7 +313,7 @@ fn check_solutions(
fmt_cmd
.arg("--check")
.arg("--edition")
.arg("2021")
.arg("2024")
.arg("--color")
.arg("always")
.stdin(Stdio::null());

View file

@ -1,4 +1,4 @@
use anyhow::{bail, Context, Result};
use anyhow::{Context, Result, bail};
use std::{
env::set_current_dir,
fs::{self, create_dir},
@ -6,7 +6,7 @@ use std::{
process::Command,
};
use crate::{init::RUST_ANALYZER_TOML, CURRENT_FORMAT_VERSION};
use crate::{CURRENT_FORMAT_VERSION, init::RUST_ANALYZER_TOML};
// Create a directory relative to the current directory and print its path.
fn create_rel_dir(dir_name: &str, current_dir: &str) -> Result<()> {
@ -55,7 +55,9 @@ pub fn new(path: &Path, no_git: bool) -> Result<()> {
write_rel_file(
"info.toml",
&dir_path_str,
format!("{INFO_FILE_BEFORE_FORMAT_VERSION}{CURRENT_FORMAT_VERSION}{INFO_FILE_AFTER_FORMAT_VERSION}"),
format!(
"{INFO_FILE_BEFORE_FORMAT_VERSION}{CURRENT_FORMAT_VERSION}{INFO_FILE_AFTER_FORMAT_VERSION}"
),
)?;
write_rel_file("Cargo.toml", &dir_path_str, CARGO_TOML)?;
@ -130,7 +132,7 @@ bin = []
[package]
name = "exercises"
edition = "2021"
edition = "2024"
# Don't publish the exercises on crates.io!
publish = false

View file

@ -1,13 +1,13 @@
use anyhow::Result;
use crossterm::{
style::{Attribute, Color, ResetColor, SetAttribute, SetForegroundColor},
QueueableCommand,
style::{Attribute, Color, ResetColor, SetAttribute, SetForegroundColor},
};
use std::io::{self, StdoutLock, Write};
use crate::{
cmd::CmdRunner,
term::{self, terminal_file_link, write_ansi, CountedWrite},
term::{self, CountedWrite, terminal_file_link, write_ansi},
};
/// The initial capacity of the output buffer.

View file

@ -1,4 +1,4 @@
use anyhow::{bail, Context, Error, Result};
use anyhow::{Context, Error, Result, bail};
use serde::Deserialize;
use std::{fs, io::ErrorKind};

View file

@ -1,7 +1,7 @@
use anyhow::{bail, Context, Result};
use anyhow::{Context, Result, bail};
use crossterm::{
style::{Attribute, Color, ResetColor, SetAttribute, SetForegroundColor},
QueueableCommand,
style::{Attribute, Color, ResetColor, SetAttribute, SetForegroundColor},
};
use serde::Deserialize;
use std::{
@ -57,7 +57,9 @@ pub fn init() -> Result<()> {
if !workspace_manifest_content.contains("[workspace]\n")
&& !workspace_manifest_content.contains("workspace.")
{
bail!("The current directory is already part of a Cargo project.\nPlease initialize Rustlings in a different directory");
bail!(
"The current directory is already part of a Cargo project.\nPlease initialize Rustlings in a different directory"
);
}
stdout.write_all(b"This command will create the directory `rustlings/` as a member of this Cargo workspace.\nPress ENTER to continue ")?;
@ -75,7 +77,9 @@ pub fn init() -> Result<()> {
.stdout(Stdio::null())
.status()?;
if !status.success() {
bail!("Failed to initialize a new Cargo workspace member.\nPlease initialize Rustlings in a different directory");
bail!(
"Failed to initialize a new Cargo workspace member.\nPlease initialize Rustlings in a different directory"
);
}
stdout.write_all(b"The directory `rustlings` has been added to `workspace.members` in the `Cargo.toml` file of this Cargo workspace.\n")?;

View file

@ -1,14 +1,13 @@
use anyhow::{Context, Result};
use crossterm::{
cursor,
QueueableCommand, cursor,
event::{
self, DisableMouseCapture, EnableMouseCapture, Event, KeyCode, KeyEventKind, MouseEventKind,
},
terminal::{
disable_raw_mode, enable_raw_mode, DisableLineWrap, EnableLineWrap, EnterAlternateScreen,
LeaveAlternateScreen,
DisableLineWrap, EnableLineWrap, EnterAlternateScreen, LeaveAlternateScreen,
disable_raw_mode, enable_raw_mode,
},
QueueableCommand,
};
use std::io::{self, StdoutLock, Write};

View file

@ -1,11 +1,11 @@
use anyhow::{Context, Result};
use crossterm::{
QueueableCommand,
cursor::{MoveTo, MoveToNextLine},
style::{
Attribute, Attributes, Color, ResetColor, SetAttribute, SetAttributes, SetForegroundColor,
},
terminal::{self, BeginSynchronizedUpdate, Clear, ClearType, EndSynchronizedUpdate},
QueueableCommand,
};
use std::{
fmt::Write as _,
@ -15,7 +15,7 @@ use std::{
use crate::{
app_state::AppState,
exercise::Exercise,
term::{progress_bar, CountedWrite, MaxLenWriter},
term::{CountedWrite, MaxLenWriter, progress_bar},
};
use super::scroll_state::ScrollState;

View file

@ -1,4 +1,4 @@
use anyhow::{bail, Context, Result};
use anyhow::{Context, Result, bail};
use app_state::StateFileStatus;
use clap::{Parser, Subcommand};
use std::{

View file

@ -1,7 +1,7 @@
use anyhow::Result;
use crossterm::{
style::{Color, ResetColor, SetForegroundColor},
QueueableCommand,
style::{Color, ResetColor, SetForegroundColor},
};
use std::{
io::{self, Write},
@ -10,7 +10,7 @@ use std::{
use crate::{
app_state::{AppState, ExercisesProgress},
exercise::{solution_link_line, RunnableExercise, OUTPUT_CAPACITY},
exercise::{OUTPUT_CAPACITY, RunnableExercise, solution_link_line},
};
pub fn run(app_state: &mut AppState) -> Result<ExitCode> {

View file

@ -1,8 +1,8 @@
use crossterm::{
Command, QueueableCommand,
cursor::MoveTo,
style::{Attribute, Color, ResetColor, SetAttribute, SetForegroundColor},
terminal::{Clear, ClearType},
Command, QueueableCommand,
};
use std::{
fmt, fs,

View file

@ -74,7 +74,9 @@ fn run_watch(
let mut watcher = RecommendedWatcher::new(
notify_event_handler,
Config::default().with_poll_interval(Duration::from_secs(1)),
Config::default()
.with_follow_symlinks(false)
.with_poll_interval(Duration::from_secs(1)),
)
.inspect_err(|_| eprintln!("{NOTIFY_ERR}"))?;

View file

@ -1,18 +1,18 @@
use anyhow::{Context, Result};
use notify::{
event::{AccessKind, AccessMode, MetadataKind, ModifyKind, RenameMode},
Event, EventKind,
event::{AccessKind, AccessMode, MetadataKind, ModifyKind, RenameMode},
};
use std::{
sync::{
atomic::Ordering::Relaxed,
mpsc::{sync_channel, RecvTimeoutError, Sender, SyncSender},
mpsc::{RecvTimeoutError, Sender, SyncSender, sync_channel},
},
thread,
time::Duration,
};
use super::{WatchEvent, EXERCISE_RUNNING};
use super::{EXERCISE_RUNNING, WatchEvent};
const DEBOUNCE_DURATION: Duration = Duration::from_millis(200);

View file

@ -1,24 +1,25 @@
use anyhow::{Context, Result};
use crossterm::{
QueueableCommand,
style::{
Attribute, Attributes, Color, ResetColor, SetAttribute, SetAttributes, SetForegroundColor,
},
terminal, QueueableCommand,
terminal,
};
use std::{
io::{self, Read, StdoutLock, Write},
sync::mpsc::{sync_channel, Sender, SyncSender},
sync::mpsc::{Sender, SyncSender, sync_channel},
thread,
};
use crate::{
app_state::{AppState, ExercisesProgress},
clear_terminal,
exercise::{solution_link_line, RunnableExercise, OUTPUT_CAPACITY},
exercise::{OUTPUT_CAPACITY, RunnableExercise, solution_link_line},
term::progress_bar,
};
use super::{terminal_event::terminal_event_handler, InputPauseGuard, WatchEvent};
use super::{InputPauseGuard, WatchEvent, terminal_event::terminal_event_handler};
const HEADING_ATTRIBUTES: Attributes = Attributes::none()
.with(Attribute::Bold)

View file

@ -4,7 +4,7 @@ use std::sync::{
mpsc::{Receiver, Sender},
};
use super::{WatchEvent, EXERCISE_RUNNING};
use super::{EXERCISE_RUNNING, WatchEvent};
pub enum InputEvent {
Next,

View file

@ -7,5 +7,5 @@ bin = [
[package]
name = "test_exercises"
edition = "2021"
edition = "2024"
publish = false