summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main.rs32
-rw-r--r--src/verify.rs12
2 files changed, 36 insertions, 8 deletions
diff --git a/src/main.rs b/src/main.rs
index 9505650..ebb61d6 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -6,9 +6,12 @@ use notify::DebouncedEvent;
use notify::{RecommendedWatcher, RecursiveMode, Watcher};
use std::ffi::OsStr;
use std::fs;
+use std::io;
use std::path::Path;
use std::process::{Command, Stdio};
use std::sync::mpsc::channel;
+use std::sync::{Arc, Mutex};
+use std::thread;
use std::time::Duration;
mod exercise;
@@ -108,6 +111,26 @@ fn main() {
}
}
+fn spawn_watch_shell(failed_exercise_hint: &Arc<Mutex<Option<String>>>) {
+ let failed_exercise_hint = Arc::clone(failed_exercise_hint);
+ println!("Type 'hint' to get help");
+ thread::spawn(move || loop {
+ let mut input = String::new();
+ match io::stdin().read_line(&mut input) {
+ Ok(_) => {
+ if input.trim().eq("hint") {
+ if let Some(hint) = &*failed_exercise_hint.lock().unwrap() {
+ println!("{}", hint);
+ }
+ } else {
+ println!("unknown command: {}", input);
+ }
+ }
+ Err(error) => println!("error reading command: {}", error),
+ }
+ });
+}
+
fn watch(exercises: &[Exercise]) -> notify::Result<()> {
/* Clears the terminal with an ANSI escape code.
Works in UNIX and newer Windows terminals. */
@@ -121,8 +144,11 @@ fn watch(exercises: &[Exercise]) -> notify::Result<()> {
watcher.watch(Path::new("./exercises"), RecursiveMode::Recursive)?;
clear_screen();
- let _ignored = verify(exercises.iter());
+ let verify_result = verify(exercises.iter());
+ let to_owned_hint = |t: &Exercise| t.hint.to_owned();
+ let failed_exercise_hint = Arc::new(Mutex::new(verify_result.map_err(to_owned_hint).err()));
+ spawn_watch_shell(&failed_exercise_hint);
loop {
match rx.recv() {
Ok(event) => match event {
@@ -133,7 +159,9 @@ fn watch(exercises: &[Exercise]) -> notify::Result<()> {
.iter()
.skip_while(|e| !filepath.ends_with(&e.path));
clear_screen();
- let _ignored = verify(pending_exercises);
+ let verify_result = verify(pending_exercises);
+ let mut failed_exercise_hint = failed_exercise_hint.lock().unwrap();
+ *failed_exercise_hint = verify_result.map_err(to_owned_hint).err();
}
}
_ => {}
diff --git a/src/verify.rs b/src/verify.rs
index c499c4a..3796bbd 100644
--- a/src/verify.rs
+++ b/src/verify.rs
@@ -2,14 +2,14 @@ use crate::exercise::{Exercise, Mode, State};
use console::{style, Emoji};
use indicatif::ProgressBar;
-pub fn verify<'a>(start_at: impl IntoIterator<Item = &'a Exercise>) -> Result<(), ()> {
+pub fn verify<'a>(start_at: impl IntoIterator<Item = &'a Exercise>) -> Result<(), &'a Exercise> {
for exercise in start_at {
- let is_done = match exercise.mode {
- Mode::Test => compile_and_test_interactively(&exercise)?,
- Mode::Compile => compile_only(&exercise)?,
+ let compile_result = match exercise.mode {
+ Mode::Test => compile_and_test_interactively(&exercise),
+ Mode::Compile => compile_only(&exercise),
};
- if !is_done {
- return Err(());
+ if !compile_result.unwrap_or(false) {
+ return Err(exercise);
}
}
Ok(())