summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main.rs19
-rw-r--r--src/watch.rs27
-rw-r--r--src/watch/state.rs5
3 files changed, 37 insertions, 14 deletions
diff --git a/src/main.rs b/src/main.rs
index 504c02d..fc83e0f 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -16,9 +16,11 @@ mod watch;
use self::{
consts::WELCOME,
exercise::{Exercise, InfoFile},
+ list::list,
run::run,
state_file::StateFile,
verify::{verify, VerifyState},
+ watch::{watch, WatchExit},
};
/// Rustlings is a collection of small exercises to get you used to writing and reading Rust code
@@ -52,8 +54,6 @@ enum Subcommands {
/// The name of the exercise
name: String,
},
- /// List the exercises available in Rustlings
- List,
}
fn find_exercise(name: &str, exercises: &'static [Exercise]) -> Result<(usize, &'static Exercise)> {
@@ -112,14 +112,17 @@ If you are just starting with Rustlings, run the command `rustlings init` to ini
let mut state_file = StateFile::read_or_default(exercises);
match args.command {
- None | Some(Subcommands::Watch) => {
- watch::watch(&state_file, exercises)?;
- }
+ None | Some(Subcommands::Watch) => loop {
+ match watch(&mut state_file, exercises)? {
+ WatchExit::Shutdown => break,
+ // It is much easier to exit the watch mode, launch the list mode and then restart
+ // the watch mode instead of trying to pause the watch threads and correct the
+ // watch state.
+ WatchExit::List => list(&mut state_file, exercises)?,
+ }
+ },
// `Init` is handled above.
Some(Subcommands::Init) => (),
- Some(Subcommands::List) => {
- list::list(&mut state_file, exercises)?;
- }
Some(Subcommands::Run { name }) => {
let (_, exercise) = find_exercise(&name, exercises)?;
run(exercise).unwrap_or_else(|_| exit(1));
diff --git a/src/watch.rs b/src/watch.rs
index 6324eb3..004a13f 100644
--- a/src/watch.rs
+++ b/src/watch.rs
@@ -18,9 +18,19 @@ use crate::{exercise::Exercise, state_file::StateFile};
use self::state::WatchState;
+/// Returned by the watch mode to indicate what to do afterwards.
+pub enum WatchExit {
+ /// Exit the program.
+ Shutdown,
+ /// Enter the list mode and restart the watch mode afterwards.
+ List,
+}
+
+#[derive(Copy, Clone)]
enum InputEvent {
Hint,
Clear,
+ List,
Quit,
Unrecognized,
}
@@ -86,20 +96,26 @@ fn input_handler(tx: Sender<WatchEvent>) {
let event = match stdin_buf.trim() {
"h" | "hint" => InputEvent::Hint,
"c" | "clear" => InputEvent::Clear,
+ "l" | "list" => InputEvent::List,
"q" | "quit" => InputEvent::Quit,
_ => InputEvent::Unrecognized,
};
- stdin_buf.clear();
-
if tx.send(WatchEvent::Input(event)).is_err() {
// The receiver was dropped.
return;
}
+
+ match event {
+ InputEvent::List | InputEvent::Quit => return,
+ _ => (),
+ }
+
+ stdin_buf.clear();
}
}
-pub fn watch(state_file: &StateFile, exercises: &'static [Exercise]) -> Result<()> {
+pub fn watch(state_file: &mut StateFile, exercises: &'static [Exercise]) -> Result<WatchExit> {
let (tx, rx) = channel();
let mut debouncer = new_debouncer(
Duration::from_secs(1),
@@ -125,6 +141,9 @@ pub fn watch(state_file: &StateFile, exercises: &'static [Exercise]) -> Result<(
WatchEvent::Input(InputEvent::Hint) => {
watch_state.show_hint()?;
}
+ WatchEvent::Input(InputEvent::List) => {
+ return Ok(WatchExit::List);
+ }
WatchEvent::Input(InputEvent::Clear) | WatchEvent::TerminalResize => {
watch_state.render()?;
}
@@ -147,5 +166,5 @@ We hope you're enjoying learning Rust!
If you want to continue working on the exercises at a later point, you can simply run `rustlings` again.
")?;
- Ok(())
+ Ok(WatchExit::Shutdown)
}
diff --git a/src/watch/state.rs b/src/watch/state.rs
index 4db9440..393ea02 100644
--- a/src/watch/state.rs
+++ b/src/watch/state.rs
@@ -36,10 +36,11 @@ impl<'a> WatchState<'a> {
let writer = io::stdout().lock();
let prompt = format!(
- "\n\n{}int/{}lear/{}uit? ",
+ "\n\n{}int/{}lear/{}ist/{}uit? ",
"h".bold(),
"c".bold(),
- "q".bold()
+ "l".bold(),
+ "q".bold(),
)
.into_bytes();