mirror of
https://github.com/rust-lang/rustlings.git
synced 2024-12-25 23:10:30 +00:00
Merge branch 'main' into which
This commit is contained in:
commit
8e0f7e56f7
6 changed files with 29 additions and 44 deletions
10
Cargo.lock
generated
10
Cargo.lock
generated
|
@ -271,15 +271,6 @@ version = "0.4.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
||||
|
||||
[[package]]
|
||||
name = "home"
|
||||
version = "0.5.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5"
|
||||
dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.2.5"
|
||||
|
@ -564,7 +555,6 @@ dependencies = [
|
|||
"clap",
|
||||
"console",
|
||||
"glob",
|
||||
"home",
|
||||
"indicatif",
|
||||
"notify-debouncer-mini",
|
||||
"predicates",
|
||||
|
|
|
@ -12,7 +12,6 @@ edition = "2021"
|
|||
clap = { version = "4.5.2", features = ["derive"] }
|
||||
console = "0.15.8"
|
||||
glob = "0.3.0"
|
||||
home = "0.5.9"
|
||||
indicatif = "0.17.8"
|
||||
notify-debouncer-mini = "0.4.1"
|
||||
regex = "1.10.3"
|
||||
|
|
|
@ -58,7 +58,7 @@ pub struct Exercise {
|
|||
|
||||
// An enum to track of the state of an Exercise.
|
||||
// An Exercise can be either Done or Pending
|
||||
#[derive(PartialEq, Debug)]
|
||||
#[derive(PartialEq, Eq, Debug)]
|
||||
pub enum State {
|
||||
// The state of the exercise once it's been completed
|
||||
Done,
|
||||
|
@ -67,7 +67,7 @@ pub enum State {
|
|||
}
|
||||
|
||||
// The context information of a pending exercise
|
||||
#[derive(PartialEq, Debug)]
|
||||
#[derive(PartialEq, Eq, Debug)]
|
||||
pub struct ContextLine {
|
||||
// The source code that is still pending completion
|
||||
pub line: String,
|
||||
|
|
20
src/main.rs
20
src/main.rs
|
@ -217,16 +217,13 @@ fn main() {
|
|||
println!("Failed to write rust-project.json to disk for rust-analyzer");
|
||||
} else {
|
||||
println!("Successfully generated rust-project.json");
|
||||
println!("rust-analyzer will now parse exercises, restart your language server or editor")
|
||||
println!("rust-analyzer will now parse exercises, restart your language server or editor");
|
||||
}
|
||||
}
|
||||
|
||||
Subcommands::Watch { success_hints } => match watch(&exercises, verbose, success_hints) {
|
||||
Err(e) => {
|
||||
println!(
|
||||
"Error: Could not watch your progress. Error message was {:?}.",
|
||||
e
|
||||
);
|
||||
println!("Error: Could not watch your progress. Error message was {e:?}.");
|
||||
println!("Most likely you've run out of disk space or your 'inotify limit' has been reached.");
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
@ -280,7 +277,7 @@ fn spawn_watch_shell(
|
|||
if parts.is_empty() {
|
||||
println!("no command provided");
|
||||
} else if let Err(e) = Command::new(parts[0]).args(&parts[1..]).status() {
|
||||
println!("failed to execute command `{}`: {}", cmd, e);
|
||||
println!("failed to execute command `{cmd}`: {e}");
|
||||
}
|
||||
} else {
|
||||
println!("unknown command: {input}");
|
||||
|
@ -292,7 +289,7 @@ fn spawn_watch_shell(
|
|||
}
|
||||
|
||||
fn find_exercise<'a>(name: &str, exercises: &'a [Exercise]) -> &'a Exercise {
|
||||
if name.eq("next") {
|
||||
if name == "next" {
|
||||
exercises
|
||||
.iter()
|
||||
.find(|e| !e.looks_done())
|
||||
|
@ -338,7 +335,6 @@ fn watch(
|
|||
|
||||
clear_screen();
|
||||
|
||||
let to_owned_hint = |t: &Exercise| t.hint.to_owned();
|
||||
let failed_exercise_hint = match verify(
|
||||
exercises.iter(),
|
||||
(0, exercises.len()),
|
||||
|
@ -346,7 +342,7 @@ fn watch(
|
|||
success_hints,
|
||||
) {
|
||||
Ok(_) => return Ok(WatchStatus::Finished),
|
||||
Err(exercise) => Arc::new(Mutex::new(Some(to_owned_hint(exercise)))),
|
||||
Err(exercise) => Arc::new(Mutex::new(Some(exercise.hint.clone()))),
|
||||
};
|
||||
spawn_watch_shell(&failed_exercise_hint, Arc::clone(&should_quit));
|
||||
loop {
|
||||
|
@ -383,7 +379,7 @@ fn watch(
|
|||
Err(exercise) => {
|
||||
let mut failed_exercise_hint =
|
||||
failed_exercise_hint.lock().unwrap();
|
||||
*failed_exercise_hint = Some(to_owned_hint(exercise));
|
||||
*failed_exercise_hint = Some(exercise.hint.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -403,7 +399,7 @@ fn watch(
|
|||
}
|
||||
}
|
||||
|
||||
const DEFAULT_OUT: &str = r#"Thanks for installing Rustlings!
|
||||
const DEFAULT_OUT: &str = "Thanks for installing Rustlings!
|
||||
|
||||
Is this your first time? Don't worry, Rustlings was made for beginners! We are
|
||||
going to teach you a lot of things about Rust, but before we can get
|
||||
|
@ -429,7 +425,7 @@ started, here's a couple of notes about how Rustlings operates:
|
|||
autocompletion, run the command `rustlings lsp`.
|
||||
|
||||
Got all that? Great! To get started, run `rustlings watch` in order to get the first
|
||||
exercise. Make sure to have your editor open!"#;
|
||||
exercise. Make sure to have your editor open!";
|
||||
|
||||
const FENISH_LINE: &str = "+----------------------------------------------------+
|
||||
| You made it to the Fe-nish line! |
|
||||
|
|
|
@ -21,7 +21,8 @@ pub fn run(exercise: &Exercise, verbose: bool) -> Result<(), ()> {
|
|||
// Resets the exercise by stashing the changes.
|
||||
pub fn reset(exercise: &Exercise) -> Result<(), ()> {
|
||||
let command = Command::new("git")
|
||||
.args(["stash", "--"])
|
||||
.arg("stash")
|
||||
.arg("--")
|
||||
.arg(&exercise.path)
|
||||
.spawn();
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ pub fn verify<'a>(
|
|||
.progress_chars("#>-"),
|
||||
);
|
||||
bar.set_position(num_done as u64);
|
||||
bar.set_message(format!("({:.1} %)", percentage));
|
||||
bar.set_message(format!("({percentage:.1} %)"));
|
||||
|
||||
for exercise in exercises {
|
||||
let compile_result = match exercise.mode {
|
||||
|
@ -37,7 +37,7 @@ pub fn verify<'a>(
|
|||
}
|
||||
percentage += 100.0 / total as f32;
|
||||
bar.inc(1);
|
||||
bar.set_message(format!("({:.1} %)", percentage));
|
||||
bar.set_message(format!("({percentage:.1} %)"));
|
||||
if bar.position() == total as u64 {
|
||||
println!(
|
||||
"Progress: You completed {} / {} exercises ({:.1} %).",
|
||||
|
@ -51,6 +51,7 @@ pub fn verify<'a>(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
enum RunMode {
|
||||
Interactive,
|
||||
NonInteractive,
|
||||
|
@ -124,7 +125,7 @@ fn compile_and_test(
|
|||
if verbose {
|
||||
println!("{}", output.stdout);
|
||||
}
|
||||
if let RunMode::Interactive = run_mode {
|
||||
if run_mode == RunMode::Interactive {
|
||||
Ok(prompt_for_completion(exercise, None, success_hints))
|
||||
} else {
|
||||
Ok(true)
|
||||
|
@ -191,27 +192,25 @@ fn prompt_for_completion(
|
|||
Mode::Test => "The code is compiling, and the tests pass!",
|
||||
Mode::Clippy => clippy_success_msg,
|
||||
};
|
||||
println!();
|
||||
|
||||
if no_emoji {
|
||||
println!("~*~ {success_msg} ~*~")
|
||||
println!("\n~*~ {success_msg} ~*~\n");
|
||||
} else {
|
||||
println!("🎉 🎉 {success_msg} 🎉 🎉")
|
||||
println!("\n🎉 🎉 {success_msg} 🎉 🎉\n");
|
||||
}
|
||||
println!();
|
||||
|
||||
if let Some(output) = prompt_output {
|
||||
println!("Output:");
|
||||
println!("{}", separator());
|
||||
println!("{output}");
|
||||
println!("{}", separator());
|
||||
println!();
|
||||
println!(
|
||||
"Output:\n{separator}\n{output}\n{separator}\n",
|
||||
separator = separator(),
|
||||
);
|
||||
}
|
||||
if success_hints {
|
||||
println!("Hints:");
|
||||
println!("{}", separator());
|
||||
println!("{}", exercise.hint);
|
||||
println!("{}", separator());
|
||||
println!();
|
||||
println!(
|
||||
"Hints:\n{separator}\n{}\n{separator}\n",
|
||||
exercise.hint,
|
||||
separator = separator(),
|
||||
);
|
||||
}
|
||||
|
||||
println!("You can keep working on this exercise,");
|
||||
|
@ -231,7 +230,7 @@ fn prompt_for_completion(
|
|||
"{:>2} {} {}",
|
||||
style(context_line.number).blue().bold(),
|
||||
style("|").blue(),
|
||||
formatted_line
|
||||
formatted_line,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue