Skip to content

Commit f995b4c

Browse files
committed
Merge branch 'main' into watch
2 parents 27fa7c3 + b8a5886 commit f995b4c

File tree

6 files changed

+110
-78
lines changed

6 files changed

+110
-78
lines changed

Cargo.lock

Lines changed: 57 additions & 16 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@ edition = "2021"
1212
clap = { version = "4.5.2", features = ["derive"] }
1313
console = "0.15.8"
1414
glob = "0.3.0"
15-
home = "0.5.9"
1615
indicatif = "0.17.8"
1716
notify-debouncer-mini = "0.4.1"
1817
regex = "1.10.3"
1918
serde_json = "1.0.114"
2019
serde = { version = "1.0.197", features = ["derive"] }
2120
shlex = "1.3.0"
22-
toml = "0.8.10"
21+
toml_edit = { version = "0.22.9", default-features = false, features = ["parse", "serde"] }
22+
which = "6.0.1"
2323

2424
[[bin]]
2525
name = "rustlings"

src/exercise.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::fmt::{self, Display, Formatter};
55
use std::fs::{self, remove_file, File};
66
use std::io::Read;
77
use std::path::PathBuf;
8-
use std::process::{self, Command};
8+
use std::process::{self, Command, Stdio};
99

1010
const RUSTC_COLOR_ARGS: &[&str] = &["--color", "always"];
1111
const RUSTC_EDITION_ARGS: &[&str] = &["--edition", "2021"];
@@ -58,7 +58,7 @@ pub struct Exercise {
5858

5959
// An enum to track of the state of an Exercise.
6060
// An Exercise can be either Done or Pending
61-
#[derive(PartialEq, Debug)]
61+
#[derive(PartialEq, Eq, Debug)]
6262
pub enum State {
6363
// The state of the exercise once it's been completed
6464
Done,
@@ -67,7 +67,7 @@ pub enum State {
6767
}
6868

6969
// The context information of a pending exercise
70-
#[derive(PartialEq, Debug)]
70+
#[derive(PartialEq, Eq, Debug)]
7171
pub struct ContextLine {
7272
// The source code that is still pending completion
7373
pub line: String,
@@ -148,7 +148,10 @@ path = "{}.rs""#,
148148
.args(RUSTC_COLOR_ARGS)
149149
.args(RUSTC_EDITION_ARGS)
150150
.args(RUSTC_NO_DEBUG_ARGS)
151-
.output()
151+
.stdin(Stdio::null())
152+
.stdout(Stdio::null())
153+
.stderr(Stdio::null())
154+
.status()
152155
.expect("Failed to compile!");
153156
// Due to an issue with Clippy, a cargo clean is required to catch all lints.
154157
// See https://github.com/rust-lang/rust-clippy/issues/2604
@@ -157,7 +160,10 @@ path = "{}.rs""#,
157160
Command::new("cargo")
158161
.args(["clean", "--manifest-path", CLIPPY_CARGO_TOML_PATH])
159162
.args(RUSTC_COLOR_ARGS)
160-
.output()
163+
.stdin(Stdio::null())
164+
.stdout(Stdio::null())
165+
.stderr(Stdio::null())
166+
.status()
161167
.expect("Failed to run 'cargo clean'");
162168
Command::new("cargo")
163169
.args(["clippy", "--manifest-path", CLIPPY_CARGO_TOML_PATH])

src/main.rs

Lines changed: 21 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use std::ffi::OsStr;
1111
use std::fs;
1212
use std::io::{self, prelude::*};
1313
use std::path::Path;
14-
use std::process::{Command, Stdio};
14+
use std::process::Command;
1515
use std::sync::atomic::{AtomicBool, Ordering};
1616
use std::sync::mpsc::{channel, RecvTimeoutError};
1717
use std::sync::{Arc, Mutex};
@@ -92,24 +92,25 @@ fn main() {
9292
println!("\n{WELCOME}\n");
9393
}
9494

95-
if !Path::new("info.toml").exists() {
96-
println!(
97-
"{} must be run from the rustlings directory",
98-
std::env::current_exe().unwrap().to_str().unwrap()
99-
);
100-
println!("Try `cd rustlings/`!");
101-
std::process::exit(1);
102-
}
103-
104-
if !rustc_exists() {
95+
if which::which("rustc").is_err() {
10596
println!("We cannot find `rustc`.");
10697
println!("Try running `rustc --version` to diagnose your problem.");
10798
println!("For instructions on how to install Rust, check the README.");
10899
std::process::exit(1);
109100
}
110101

111-
let toml_str = &fs::read_to_string("info.toml").unwrap();
112-
let exercises = toml::from_str::<ExerciseList>(toml_str).unwrap().exercises;
102+
let info_file = fs::read_to_string("info.toml").unwrap_or_else(|e| {
103+
match e.kind() {
104+
io::ErrorKind::NotFound => println!(
105+
"The program must be run from the rustlings directory\nTry `cd rustlings/`!",
106+
),
107+
_ => println!("Failed to read the info.toml file: {e}"),
108+
}
109+
std::process::exit(1);
110+
});
111+
let exercises = toml_edit::de::from_str::<ExerciseList>(&info_file)
112+
.unwrap()
113+
.exercises;
113114
let verbose = args.nocapture;
114115

115116
let command = args.command.unwrap_or_else(|| {
@@ -218,16 +219,13 @@ fn main() {
218219
println!("Failed to write rust-project.json to disk for rust-analyzer");
219220
} else {
220221
println!("Successfully generated rust-project.json");
221-
println!("rust-analyzer will now parse exercises, restart your language server or editor")
222+
println!("rust-analyzer will now parse exercises, restart your language server or editor");
222223
}
223224
}
224225

225226
Subcommands::Watch { success_hints } => match watch(&exercises, verbose, success_hints) {
226227
Err(e) => {
227-
println!(
228-
"Error: Could not watch your progress. Error message was {:?}.",
229-
e
230-
);
228+
println!("Error: Could not watch your progress. Error message was {e:?}.");
231229
println!("Most likely you've run out of disk space or your 'inotify limit' has been reached.");
232230
std::process::exit(1);
233231
}
@@ -295,7 +293,7 @@ fn spawn_watch_shell(
295293
}
296294

297295
fn find_exercise<'a>(name: &str, exercises: &'a [Exercise]) -> &'a Exercise {
298-
if name.eq("next") {
296+
if name == "next" {
299297
exercises
300298
.iter()
301299
.find(|e| !e.looks_done())
@@ -341,15 +339,14 @@ fn watch(
341339

342340
clear_screen();
343341

344-
let to_owned_hint = |t: &Exercise| t.hint.to_owned();
345342
let failed_exercise_hint = match verify(
346343
exercises.iter(),
347344
(0, exercises.len()),
348345
verbose,
349346
success_hints,
350347
) {
351348
Ok(_) => return Ok(WatchStatus::Finished),
352-
Err(exercise) => Arc::new(Mutex::new(Some(to_owned_hint(exercise)))),
349+
Err(exercise) => Arc::new(Mutex::new(Some(exercise.hint.clone()))),
353350
};
354351
spawn_watch_shell(Arc::clone(&failed_exercise_hint), Arc::clone(&should_quit));
355352
loop {
@@ -386,7 +383,7 @@ fn watch(
386383
Err(exercise) => {
387384
let mut failed_exercise_hint =
388385
failed_exercise_hint.lock().unwrap();
389-
*failed_exercise_hint = Some(to_owned_hint(exercise));
386+
*failed_exercise_hint = Some(exercise.hint.clone());
390387
}
391388
}
392389
}
@@ -406,19 +403,7 @@ fn watch(
406403
}
407404
}
408405

409-
fn rustc_exists() -> bool {
410-
Command::new("rustc")
411-
.args(["--version"])
412-
.stdout(Stdio::null())
413-
.stderr(Stdio::null())
414-
.stdin(Stdio::null())
415-
.spawn()
416-
.and_then(|mut child| child.wait())
417-
.map(|status| status.success())
418-
.unwrap_or(false)
419-
}
420-
421-
const DEFAULT_OUT: &str = r#"Thanks for installing Rustlings!
406+
const DEFAULT_OUT: &str = "Thanks for installing Rustlings!
422407
423408
Is this your first time? Don't worry, Rustlings was made for beginners! We are
424409
going to teach you a lot of things about Rust, but before we can get
@@ -444,7 +429,7 @@ started, here's a couple of notes about how Rustlings operates:
444429
autocompletion, run the command `rustlings lsp`.
445430
446431
Got all that? Great! To get started, run `rustlings watch` in order to get the first
447-
exercise. Make sure to have your editor open!"#;
432+
exercise. Make sure to have your editor open!";
448433

449434
const FENISH_LINE: &str = "+----------------------------------------------------+
450435
| You made it to the Fe-nish line! |

src/run.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ pub fn run(exercise: &Exercise, verbose: bool) -> Result<(), ()> {
2121
// Resets the exercise by stashing the changes.
2222
pub fn reset(exercise: &Exercise) -> Result<(), ()> {
2323
let command = Command::new("git")
24-
.args(["stash", "--"])
24+
.arg("stash")
25+
.arg("--")
2526
.arg(&exercise.path)
2627
.spawn();
2728

0 commit comments

Comments
 (0)