Trigger check all when an exercise is done but not marked as such

This commit is contained in:
mo8it 2026-08-02 14:18:11 +02:00
parent dd758b79ba
commit 8168c0fced
2 changed files with 35 additions and 23 deletions

View File

@ -43,7 +43,6 @@ enum WatchEvent {
Input(InputEvent),
FileChange { exercise_ind: usize },
TerminalResize { width: u16 },
CheckAll,
NotifyErr(notify::Error),
TerminalEventErr(io::Error),
}
@ -97,7 +96,20 @@ fn run_watch(
match event {
WatchEvent::Input(InputEvent::Next) => match watch_state.next_exercise(&mut stdout)? {
ExercisesProgress::AllDone => break,
ExercisesProgress::NewPending => watch_state.run_current_exercise(&mut stdout)?,
ExercisesProgress::NewPending => {
watch_state.run_current_exercise(&mut stdout)?;
if watch_state.done() {
// An exercise is done although it was not marked as such.
// Trigger check all to fix the state file.
match watch_state.check_all_exercises(&mut stdout)? {
ExercisesProgress::AllDone => break,
ExercisesProgress::NewPending => {
watch_state.run_current_exercise(&mut stdout)?;
}
ExercisesProgress::CurrentPending => watch_state.render(&mut stdout)?,
}
}
}
ExercisesProgress::CurrentPending => (),
},
WatchEvent::Input(InputEvent::Run) => watch_state.run_current_exercise(&mut stdout)?,
@ -114,11 +126,6 @@ fn run_watch(
WatchEvent::TerminalResize { width } => {
watch_state.update_term_width(width, &mut stdout)?;
}
WatchEvent::CheckAll => match watch_state.check_all_exercises(&mut stdout)? {
ExercisesProgress::AllDone => break,
ExercisesProgress::NewPending => watch_state.run_current_exercise(&mut stdout)?,
ExercisesProgress::CurrentPending => watch_state.render(&mut stdout)?,
},
WatchEvent::NotifyErr(e) => return Err(Error::from(e).context(NOTIFY_ERR)),
WatchEvent::TerminalEventErr(e) => {
return Err(Error::from(e).context("Terminal event listener failed"));

View File

@ -24,7 +24,6 @@ const HEADING_ATTRIBUTES: Attributes = Attributes::none()
.with(Attribute::Bold)
.with(Attribute::Underlined);
#[derive(PartialEq, Eq)]
enum DoneStatus {
DoneWithSolution(String),
DoneWithoutSolution,
@ -93,19 +92,19 @@ impl<'a> WatchState<'a> {
.current_exercise()
.run_exercise(Some(&mut self.output), self.app_state.cmd_runner())?;
self.output.push(b'\n');
if success {
self.done_status =
if let Some(solution_path) = self.app_state.current_solution_path()? {
DoneStatus::DoneWithSolution(solution_path)
} else {
DoneStatus::DoneWithoutSolution
};
self.done_status = if success {
if let Some(solution_path) = self.app_state.current_solution_path()? {
DoneStatus::DoneWithSolution(solution_path)
} else {
DoneStatus::DoneWithoutSolution
}
} else {
self.app_state
.set_pending(self.app_state.current_exercise_ind())?;
self.done_status = DoneStatus::Pending;
}
DoneStatus::Pending
};
self.app_state.join_editor_handle(editor_handle)?;
self.render(stdout)?;
@ -164,18 +163,24 @@ impl<'a> WatchState<'a> {
self.run_current_exercise(stdout)
}
pub fn done(&self) -> bool {
match self.done_status {
DoneStatus::DoneWithSolution(_) | DoneStatus::DoneWithoutSolution => true,
DoneStatus::Pending => false,
}
}
/// Move on to the next exercise if the current one is done.
pub fn next_exercise(&mut self, stdout: &mut StdoutLock) -> Result<ExercisesProgress> {
match self.done_status {
DoneStatus::DoneWithSolution(_) | DoneStatus::DoneWithoutSolution => (),
DoneStatus::Pending => return Ok(ExercisesProgress::CurrentPending),
if self.done() {
return self.app_state.done_current_exercise::<true>(stdout);
}
self.app_state.done_current_exercise::<true>(stdout)
Ok(ExercisesProgress::CurrentPending)
}
fn show_prompt(&self, stdout: &mut StdoutLock) -> io::Result<()> {
if self.done_status != DoneStatus::Pending {
if self.done() {
stdout.queue(SetAttribute(Attribute::Bold))?;
stdout.write_all(b"n")?;
stdout.queue(ResetColor)?;
@ -233,7 +238,7 @@ impl<'a> WatchState<'a> {
stdout.write_all(b"\n\n")?;
}
if self.done_status != DoneStatus::Pending {
if self.done() {
stdout
.queue(SetAttribute(Attribute::Bold))?
.queue(SetForegroundColor(Color::Green))?;