Skip to content

Commit d9872f2

Browse files
committed
Upgrade to edition 2024
1 parent 298be67 commit d9872f2

File tree

20 files changed

+122
-81
lines changed

20 files changed

+122
-81
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
## Unreleased
2+
3+
### Changed
4+
5+
- Upgrade to Rust edition 2024
6+
- Raise the minimum supported Rust version to `1.85`
7+
18
<a name="6.4.0"></a>
29

310
## 6.4.0 (2024-11-11)

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ authors = [
1515
]
1616
repository = "https://github.com/rust-lang/rustlings"
1717
license = "MIT"
18-
edition = "2021" # On Update: Update the edition of the `rustfmt` command that checks the solutions.
19-
rust-version = "1.80"
18+
edition = "2024" # On Update: Update the edition of the `rustfmt` command that checks the solutions.
19+
rust-version = "1.85"
2020

2121
[workspace.dependencies]
2222
serde = { version = "1.0.217", features = ["derive"] }

dev/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ bin = [
192192

193193
[package]
194194
name = "exercises"
195-
edition = "2021"
195+
edition = "2024"
196196
# Don't publish the exercises on crates.io!
197197
publish = false
198198

src/app_state.rs

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
use anyhow::{bail, Context, Error, Result};
2-
use crossterm::{cursor, terminal, QueueableCommand};
1+
use anyhow::{Context, Error, Result, bail};
2+
use crossterm::{QueueableCommand, cursor, terminal};
33
use std::{
44
collections::HashSet,
55
env,
66
fs::{File, OpenOptions},
77
io::{Read, Seek, StdoutLock, Write},
8-
path::{Path, MAIN_SEPARATOR_STR},
8+
path::{MAIN_SEPARATOR_STR, Path},
99
process::{Command, Stdio},
1010
sync::{
1111
atomic::{AtomicUsize, Ordering::Relaxed},
@@ -427,32 +427,34 @@ impl AppState {
427427
let next_exercise_ind = &next_exercise_ind;
428428
let slf = &self;
429429
thread::Builder::new()
430-
.spawn_scoped(s, move || loop {
431-
let exercise_ind = next_exercise_ind.fetch_add(1, Relaxed);
432-
let Some(exercise) = slf.exercises.get(exercise_ind) else {
433-
// No more exercises.
434-
break;
435-
};
436-
437-
if exercise_progress_sender
438-
.send((exercise_ind, CheckProgress::Checking))
439-
.is_err()
440-
{
441-
break;
442-
};
443-
444-
let success = exercise.run_exercise(None, &slf.cmd_runner);
445-
let progress = match success {
446-
Ok(true) => CheckProgress::Done,
447-
Ok(false) => CheckProgress::Pending,
448-
Err(_) => CheckProgress::None,
449-
};
450-
451-
if exercise_progress_sender
452-
.send((exercise_ind, progress))
453-
.is_err()
454-
{
455-
break;
430+
.spawn_scoped(s, move || {
431+
loop {
432+
let exercise_ind = next_exercise_ind.fetch_add(1, Relaxed);
433+
let Some(exercise) = slf.exercises.get(exercise_ind) else {
434+
// No more exercises.
435+
break;
436+
};
437+
438+
if exercise_progress_sender
439+
.send((exercise_ind, CheckProgress::Checking))
440+
.is_err()
441+
{
442+
break;
443+
};
444+
445+
let success = exercise.run_exercise(None, &slf.cmd_runner);
446+
let progress = match success {
447+
Ok(true) => CheckProgress::Done,
448+
Ok(false) => CheckProgress::Pending,
449+
Err(_) => CheckProgress::None,
450+
};
451+
452+
if exercise_progress_sender
453+
.send((exercise_ind, progress))
454+
.is_err()
455+
{
456+
break;
457+
}
456458
}
457459
})
458460
.context("Failed to spawn a thread to check all exercises")?;

src/cmd.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use anyhow::{bail, Context, Result};
1+
use anyhow::{Context, Result, bail};
22
use serde::Deserialize;
33
use std::{
44
io::Read,

src/dev.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use anyhow::{bail, Context, Result};
1+
use anyhow::{Context, Result, bail};
22
use clap::Subcommand;
33
use std::path::PathBuf;
44

src/dev/check.rs

Lines changed: 43 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
1-
use anyhow::{anyhow, bail, Context, Error, Result};
1+
use anyhow::{Context, Error, Result, anyhow, bail};
22
use std::{
33
cmp::Ordering,
44
collections::HashSet,
5-
fs::{self, read_dir, OpenOptions},
5+
fs::{self, OpenOptions, read_dir},
66
io::{self, Read, Write},
77
path::{Path, PathBuf},
88
process::{Command, Stdio},
99
thread,
1010
};
1111

1212
use crate::{
13-
cargo_toml::{append_bins, bins_start_end_ind, BINS_BUFFER_CAPACITY},
13+
CURRENT_FORMAT_VERSION,
14+
cargo_toml::{BINS_BUFFER_CAPACITY, append_bins, bins_start_end_ind},
1415
cmd::CmdRunner,
15-
exercise::{RunnableExercise, OUTPUT_CAPACITY},
16+
exercise::{OUTPUT_CAPACITY, RunnableExercise},
1617
info_file::{ExerciseInfo, InfoFile},
17-
CURRENT_FORMAT_VERSION,
1818
};
1919

2020
const MAX_N_EXERCISES: usize = 999;
@@ -42,10 +42,14 @@ fn check_cargo_toml(
4242

4343
if old_bins != new_bins {
4444
if cfg!(debug_assertions) {
45-
bail!("The file `dev/Cargo.toml` is outdated. Run `cargo run -- dev update` to update it. Then run `cargo run -- dev check` again");
45+
bail!(
46+
"The file `dev/Cargo.toml` is outdated. Run `cargo run -- dev update` to update it. Then run `cargo run -- dev check` again"
47+
);
4648
}
4749

48-
bail!("The file `Cargo.toml` is outdated. Run `rustlings dev update` to update it. Then run `rustlings dev check` again");
50+
bail!(
51+
"The file `Cargo.toml` is outdated. Run `rustlings dev update` to update it. Then run `rustlings dev check` again"
52+
);
4953
}
5054

5155
Ok(())
@@ -63,7 +67,9 @@ fn check_info_file_exercises(info_file: &InfoFile) -> Result<HashSet<PathBuf>> {
6367
bail!("Found an empty exercise name in `info.toml`");
6468
}
6569
if name.len() > MAX_EXERCISE_NAME_LEN {
66-
bail!("The length of the exercise name `{name}` is bigger than the maximum {MAX_EXERCISE_NAME_LEN}");
70+
bail!(
71+
"The length of the exercise name `{name}` is bigger than the maximum {MAX_EXERCISE_NAME_LEN}"
72+
);
6773
}
6874
if let Some(c) = forbidden_char(name) {
6975
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>> {
7985
}
8086

8187
if exercise_info.hint.trim_ascii().is_empty() {
82-
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");
88+
bail!(
89+
"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"
90+
);
8391
}
8492

8593
if !names.insert(name) {
@@ -96,20 +104,28 @@ fn check_info_file_exercises(info_file: &InfoFile) -> Result<HashSet<PathBuf>> {
96104
.with_context(|| format!("Failed to read the file {path}"))?;
97105

98106
if !file_buf.contains("fn main()") {
99-
bail!("The `main` function is missing in the file `{path}`.\nCreate at least an empty `main` function to avoid language server errors");
107+
bail!(
108+
"The `main` function is missing in the file `{path}`.\nCreate at least an empty `main` function to avoid language server errors"
109+
);
100110
}
101111

102112
if !file_buf.contains("// TODO") {
103-
bail!("Didn't find any `// TODO` comment in the file `{path}`.\nYou need to have at least one such comment to guide the user.");
113+
bail!(
114+
"Didn't find any `// TODO` comment in the file `{path}`.\nYou need to have at least one such comment to guide the user."
115+
);
104116
}
105117

106118
let contains_tests = file_buf.contains("#[test]\n");
107119
if exercise_info.test {
108120
if !contains_tests {
109-
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");
121+
bail!(
122+
"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"
123+
);
110124
}
111125
} else if contains_tests {
112-
bail!("The file `{path}` contains tests annotated with `#[test]` but the exercise `{name}` has `test = false` in the `info.toml` file");
126+
bail!(
127+
"The file `{path}` contains tests annotated with `#[test]` but the exercise `{name}` has `test = false` in the `info.toml` file"
128+
);
113129
}
114130

115131
file_buf.clear();
@@ -125,7 +141,10 @@ fn check_info_file_exercises(info_file: &InfoFile) -> Result<HashSet<PathBuf>> {
125141
// Only one level of directory nesting is allowed.
126142
fn check_unexpected_files(dir: &str, allowed_rust_files: &HashSet<PathBuf>) -> Result<()> {
127143
let unexpected_file = |path: &Path| {
128-
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())
144+
anyhow!(
145+
"Found the file `{}`. Only `README.md` and Rust files related to an exercise in `info.toml` are allowed in the `{dir}` directory",
146+
path.display()
147+
)
129148
};
130149

131150
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
154173
let path = entry.path();
155174

156175
if !entry.file_type().unwrap().is_file() {
157-
bail!("Found `{}` but expected only files. Only one level of exercise nesting is allowed", path.display());
176+
bail!(
177+
"Found `{}` but expected only files. Only one level of exercise nesting is allowed",
178+
path.display()
179+
);
158180
}
159181

160182
let file_name = path.file_name().unwrap();
@@ -224,8 +246,12 @@ fn check_exercises_unsolved(
224246

225247
fn check_exercises(info_file: &'static InfoFile, cmd_runner: &'static CmdRunner) -> Result<()> {
226248
match info_file.format_version.cmp(&CURRENT_FORMAT_VERSION) {
227-
Ordering::Less => bail!("`format_version` < {CURRENT_FORMAT_VERSION} (supported version)\nPlease migrate to the latest format version"),
228-
Ordering::Greater => bail!("`format_version` > {CURRENT_FORMAT_VERSION} (supported version)\nTry updating the Rustlings program"),
249+
Ordering::Less => bail!(
250+
"`format_version` < {CURRENT_FORMAT_VERSION} (supported version)\nPlease migrate to the latest format version"
251+
),
252+
Ordering::Greater => bail!(
253+
"`format_version` > {CURRENT_FORMAT_VERSION} (supported version)\nTry updating the Rustlings program"
254+
),
229255
Ordering::Equal => (),
230256
}
231257

src/dev/new.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
use anyhow::{bail, Context, Result};
1+
use anyhow::{Context, Result, bail};
22
use std::{
33
env::set_current_dir,
44
fs::{self, create_dir},
55
path::Path,
66
process::Command,
77
};
88

9-
use crate::{init::RUST_ANALYZER_TOML, CURRENT_FORMAT_VERSION};
9+
use crate::{CURRENT_FORMAT_VERSION, init::RUST_ANALYZER_TOML};
1010

1111
// Create a directory relative to the current directory and print its path.
1212
fn create_rel_dir(dir_name: &str, current_dir: &str) -> Result<()> {
@@ -55,7 +55,9 @@ pub fn new(path: &Path, no_git: bool) -> Result<()> {
5555
write_rel_file(
5656
"info.toml",
5757
&dir_path_str,
58-
format!("{INFO_FILE_BEFORE_FORMAT_VERSION}{CURRENT_FORMAT_VERSION}{INFO_FILE_AFTER_FORMAT_VERSION}"),
58+
format!(
59+
"{INFO_FILE_BEFORE_FORMAT_VERSION}{CURRENT_FORMAT_VERSION}{INFO_FILE_AFTER_FORMAT_VERSION}"
60+
),
5961
)?;
6062

6163
write_rel_file("Cargo.toml", &dir_path_str, CARGO_TOML)?;
@@ -130,7 +132,7 @@ bin = []
130132
131133
[package]
132134
name = "exercises"
133-
edition = "2021"
135+
edition = "2024"
134136
# Don't publish the exercises on crates.io!
135137
publish = false
136138

src/exercise.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
use anyhow::Result;
22
use crossterm::{
3-
style::{Attribute, Color, ResetColor, SetAttribute, SetForegroundColor},
43
QueueableCommand,
4+
style::{Attribute, Color, ResetColor, SetAttribute, SetForegroundColor},
55
};
66
use std::io::{self, StdoutLock, Write};
77

88
use crate::{
99
cmd::CmdRunner,
10-
term::{self, terminal_file_link, write_ansi, CountedWrite},
10+
term::{self, CountedWrite, terminal_file_link, write_ansi},
1111
};
1212

1313
/// The initial capacity of the output buffer.

src/info_file.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use anyhow::{bail, Context, Error, Result};
1+
use anyhow::{Context, Error, Result, bail};
22
use serde::Deserialize;
33
use std::{fs, io::ErrorKind};
44

0 commit comments

Comments
 (0)