diff --git a/src/main.rs b/src/main.rs index f9e0f830..7b7b1655 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,7 +8,6 @@ use console::Emoji; use notify_debouncer_mini::notify::{self, RecursiveMode}; use notify_debouncer_mini::{new_debouncer, DebouncedEventKind}; use shlex::Shlex; -use std::ffi::OsStr; use std::io::{BufRead, Write}; use std::path::Path; use std::process::{exit, Command}; @@ -344,44 +343,40 @@ fn watch( Ok(_) => return Ok(WatchStatus::Finished), Err(exercise) => Arc::new(Mutex::new(Some(exercise.hint.clone()))), }; + spawn_watch_shell(Arc::clone(&failed_exercise_hint), Arc::clone(&should_quit)); + + let mut pending_exercises = Vec::with_capacity(exercises.len()); loop { match rx.recv_timeout(Duration::from_secs(1)) { Ok(event) => match event { Ok(events) => { for event in events { - let event_path = event.path; if event.kind == DebouncedEventKind::Any - && event_path.extension() == Some(OsStr::new("rs")) - && event_path.exists() + && event.path.extension().is_some_and(|ext| ext == "rs") { - let filepath = event_path.as_path().canonicalize().unwrap(); - // TODO: Remove unwrap - let pending_exercises = exercises - .iter() - .find(|e| filepath.ends_with(&e.path)) - .into_iter() - .chain(exercises.iter().filter(|e| { - !e.looks_done().unwrap() && !filepath.ends_with(&e.path) - })); - let num_done = exercises - .iter() - .filter(|e| e.looks_done().unwrap() && !filepath.ends_with(&e.path)) - .count(); + pending_exercises.extend(exercises.iter().filter(|exercise| { + !exercise.looks_done().unwrap_or(false) + || event.path.ends_with(&exercise.path) + })); + let num_done = exercises.len() - pending_exercises.len(); + clear_screen(); + match verify( - pending_exercises, + pending_exercises.iter().copied(), (num_done, exercises.len()), verbose, success_hints, ) { Ok(_) => return Ok(WatchStatus::Finished), Err(exercise) => { - let mut failed_exercise_hint = - failed_exercise_hint.lock().unwrap(); - *failed_exercise_hint = Some(exercise.hint.clone()); + let hint = exercise.hint.clone(); + *failed_exercise_hint.lock().unwrap() = Some(hint); } } + + pending_exercises.clear(); } } } diff --git a/src/verify.rs b/src/verify.rs index adfd3b26..6e048a19 100644 --- a/src/verify.rs +++ b/src/verify.rs @@ -16,7 +16,7 @@ use crate::exercise::{Exercise, Mode, State}; // If the Exercise being verified is a test, the verbose boolean // determines whether or not the test harness outputs are displayed. pub fn verify<'a>( - exercises: impl IntoIterator, + pending_exercises: impl IntoIterator, progress: (usize, usize), verbose: bool, success_hints: bool, @@ -33,7 +33,7 @@ pub fn verify<'a>( bar.set_position(num_done as u64); bar.set_message(format!("({percentage:.1} %)")); - for exercise in exercises { + for exercise in pending_exercises { let compile_result = match exercise.mode { Mode::Test => compile_and_test(exercise, RunMode::Interactive, verbose, success_hints), Mode::Compile => compile_and_run_interactively(exercise, success_hints), @@ -45,16 +45,11 @@ pub fn verify<'a>( percentage += 100.0 / total as f32; bar.inc(1); bar.set_message(format!("({percentage:.1} %)")); - if bar.position() == total as u64 { - println!( - "Progress: You completed {} / {} exercises ({:.1} %).", - bar.position(), - total, - percentage - ); - bar.finish(); - } } + + bar.finish(); + println!("You completed all exercises!"); + Ok(()) }