mirror of
https://github.com/rust-lang/rustlings.git
synced 2025-04-18 05:28:36 +01:00
Compare commits
35 commits
rustlings-
...
main
Author | SHA1 | Date | |
---|---|---|---|
![]() |
8b4562e102 | ||
![]() |
63d8986f2a | ||
![]() |
ecaecc2f76 | ||
![]() |
78194b4441 | ||
![]() |
44699e9b1b | ||
![]() |
9978c17d5f | ||
![]() |
3cc7e0377c | ||
![]() |
d2abc359cc | ||
![]() |
7c0d269279 | ||
![]() |
8db85946af | ||
![]() |
7019f4d178 | ||
![]() |
ae444eb3da | ||
![]() |
425c9821e0 | ||
![]() |
46c6fb2c82 | ||
![]() |
374c3874af | ||
![]() |
1eb6c1e469 | ||
![]() |
06af3ffc99 | ||
![]() |
65dc019fa6 | ||
![]() |
a56ccb6f4f | ||
![]() |
d9872f2615 | ||
![]() |
298be671b9 | ||
![]() |
fbfd4f25e7 | ||
![]() |
d12735a573 | ||
![]() |
1aec7c1152 | ||
![]() |
0b55809bb9 | ||
![]() |
bde6f7470c | ||
![]() |
53ec59ed95 | ||
![]() |
ed1ee38923 | ||
![]() |
26cf4989a2 | ||
![]() |
6e60f441e9 | ||
![]() |
d07de879a7 | ||
![]() |
dd0634c483 | ||
![]() |
fc0cd8f0f8 | ||
![]() |
d5cae8ff59 | ||
![]() |
38016cb2d6 |
47 changed files with 345 additions and 255 deletions
.github/workflows
CHANGELOG.mdCargo.lockCargo.tomlREADME.mdbuild.rsdev
exercises
01_variables
03_if
08_enums
12_options
13_error_handling
21_macros
22_clippy
rustlings-macros
solutions
03_if
06_move_semantics
11_hashmaps
12_options
13_error_handling
16_lifetimes
19_smart_pointers
22_clippy
quizzes
src
app_state.rscargo_toml.rscmd.rsdev.rs
dev
exercise.rsinfo_file.rsinit.rslist.rslist
main.rsrun.rsterm.rswatch.rswatch
tests/test_exercises/dev
8
.github/workflows/rust.yml
vendored
8
.github/workflows/rust.yml
vendored
|
@ -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
|
||||
|
|
|
@ -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
251
Cargo.lock
generated
|
@ -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",
|
||||
]
|
||||
|
|
24
Cargo.toml
24
Cargo.toml
|
@ -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"
|
||||
|
|
18
README.md
18
README.md
|
@ -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
5
build.rs
Normal 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");
|
||||
}
|
|
@ -192,7 +192,7 @@ bin = [
|
|||
|
||||
[package]
|
||||
name = "exercises"
|
||||
edition = "2021"
|
||||
edition = "2024"
|
||||
# Don't publish the exercises on crates.io!
|
||||
publish = false
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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!");
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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!"),
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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`.
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 = &[
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -16,7 +16,7 @@ include = [
|
|||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
quote = "1.0.37"
|
||||
quote = "1.0"
|
||||
serde.workspace = true
|
||||
toml_edit.workspace = true
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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!"),
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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")?;
|
||||
|
|
|
@ -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(¤t_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(¤t_cargo_toml.as_bytes()[bins_end_ind..]);
|
||||
|
||||
Ok(updated_cargo_toml)
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use anyhow::{bail, Context, Result};
|
||||
use anyhow::{Context, Result, bail};
|
||||
use serde::Deserialize;
|
||||
use std::{
|
||||
io::Read,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use anyhow::{bail, Context, Result};
|
||||
use anyhow::{Context, Result, bail};
|
||||
use clap::Subcommand;
|
||||
use std::path::PathBuf;
|
||||
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use anyhow::{bail, Context, Error, Result};
|
||||
use anyhow::{Context, Error, Result, bail};
|
||||
use serde::Deserialize;
|
||||
use std::{fs, io::ErrorKind};
|
||||
|
||||
|
|
12
src/init.rs
12
src/init.rs
|
@ -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")?;
|
||||
|
|
|
@ -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};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use anyhow::{bail, Context, Result};
|
||||
use anyhow::{Context, Result, bail};
|
||||
use app_state::StateFileStatus;
|
||||
use clap::{Parser, Subcommand};
|
||||
use std::{
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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}"))?;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -4,7 +4,7 @@ use std::sync::{
|
|||
mpsc::{Receiver, Sender},
|
||||
};
|
||||
|
||||
use super::{WatchEvent, EXERCISE_RUNNING};
|
||||
use super::{EXERCISE_RUNNING, WatchEvent};
|
||||
|
||||
pub enum InputEvent {
|
||||
Next,
|
||||
|
|
|
@ -7,5 +7,5 @@ bin = [
|
|||
|
||||
[package]
|
||||
name = "test_exercises"
|
||||
edition = "2021"
|
||||
edition = "2024"
|
||||
publish = false
|
||||
|
|
Loading…
Reference in a new issue