mirror of
https://github.com/rust-lang/rustlings.git
synced 2024-12-27 00:00:03 +03:00
Make the list mode part of the watch mode
This commit is contained in:
parent
533a009257
commit
d1a965f019
19
src/main.rs
19
src/main.rs
|
@ -16,9 +16,11 @@ mod watch;
|
||||||
use self::{
|
use self::{
|
||||||
consts::WELCOME,
|
consts::WELCOME,
|
||||||
exercise::{Exercise, InfoFile},
|
exercise::{Exercise, InfoFile},
|
||||||
|
list::list,
|
||||||
run::run,
|
run::run,
|
||||||
state_file::StateFile,
|
state_file::StateFile,
|
||||||
verify::{verify, VerifyState},
|
verify::{verify, VerifyState},
|
||||||
|
watch::{watch, WatchExit},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Rustlings is a collection of small exercises to get you used to writing and reading Rust code
|
/// 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
|
/// The name of the exercise
|
||||||
name: String,
|
name: String,
|
||||||
},
|
},
|
||||||
/// List the exercises available in Rustlings
|
|
||||||
List,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_exercise(name: &str, exercises: &'static [Exercise]) -> Result<(usize, &'static Exercise)> {
|
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);
|
let mut state_file = StateFile::read_or_default(exercises);
|
||||||
|
|
||||||
match args.command {
|
match args.command {
|
||||||
None | Some(Subcommands::Watch) => {
|
None | Some(Subcommands::Watch) => loop {
|
||||||
watch::watch(&state_file, exercises)?;
|
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.
|
// `Init` is handled above.
|
||||||
Some(Subcommands::Init) => (),
|
Some(Subcommands::Init) => (),
|
||||||
Some(Subcommands::List) => {
|
|
||||||
list::list(&mut state_file, exercises)?;
|
|
||||||
}
|
|
||||||
Some(Subcommands::Run { name }) => {
|
Some(Subcommands::Run { name }) => {
|
||||||
let (_, exercise) = find_exercise(&name, exercises)?;
|
let (_, exercise) = find_exercise(&name, exercises)?;
|
||||||
run(exercise).unwrap_or_else(|_| exit(1));
|
run(exercise).unwrap_or_else(|_| exit(1));
|
||||||
|
|
27
src/watch.rs
27
src/watch.rs
|
@ -18,9 +18,19 @@ use crate::{exercise::Exercise, state_file::StateFile};
|
||||||
|
|
||||||
use self::state::WatchState;
|
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 {
|
enum InputEvent {
|
||||||
Hint,
|
Hint,
|
||||||
Clear,
|
Clear,
|
||||||
|
List,
|
||||||
Quit,
|
Quit,
|
||||||
Unrecognized,
|
Unrecognized,
|
||||||
}
|
}
|
||||||
|
@ -86,20 +96,26 @@ fn input_handler(tx: Sender<WatchEvent>) {
|
||||||
let event = match stdin_buf.trim() {
|
let event = match stdin_buf.trim() {
|
||||||
"h" | "hint" => InputEvent::Hint,
|
"h" | "hint" => InputEvent::Hint,
|
||||||
"c" | "clear" => InputEvent::Clear,
|
"c" | "clear" => InputEvent::Clear,
|
||||||
|
"l" | "list" => InputEvent::List,
|
||||||
"q" | "quit" => InputEvent::Quit,
|
"q" | "quit" => InputEvent::Quit,
|
||||||
_ => InputEvent::Unrecognized,
|
_ => InputEvent::Unrecognized,
|
||||||
};
|
};
|
||||||
|
|
||||||
stdin_buf.clear();
|
|
||||||
|
|
||||||
if tx.send(WatchEvent::Input(event)).is_err() {
|
if tx.send(WatchEvent::Input(event)).is_err() {
|
||||||
// The receiver was dropped.
|
// The receiver was dropped.
|
||||||
return;
|
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 (tx, rx) = channel();
|
||||||
let mut debouncer = new_debouncer(
|
let mut debouncer = new_debouncer(
|
||||||
Duration::from_secs(1),
|
Duration::from_secs(1),
|
||||||
|
@ -125,6 +141,9 @@ pub fn watch(state_file: &StateFile, exercises: &'static [Exercise]) -> Result<(
|
||||||
WatchEvent::Input(InputEvent::Hint) => {
|
WatchEvent::Input(InputEvent::Hint) => {
|
||||||
watch_state.show_hint()?;
|
watch_state.show_hint()?;
|
||||||
}
|
}
|
||||||
|
WatchEvent::Input(InputEvent::List) => {
|
||||||
|
return Ok(WatchExit::List);
|
||||||
|
}
|
||||||
WatchEvent::Input(InputEvent::Clear) | WatchEvent::TerminalResize => {
|
WatchEvent::Input(InputEvent::Clear) | WatchEvent::TerminalResize => {
|
||||||
watch_state.render()?;
|
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.
|
If you want to continue working on the exercises at a later point, you can simply run `rustlings` again.
|
||||||
")?;
|
")?;
|
||||||
|
|
||||||
Ok(())
|
Ok(WatchExit::Shutdown)
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,10 +36,11 @@ impl<'a> WatchState<'a> {
|
||||||
let writer = io::stdout().lock();
|
let writer = io::stdout().lock();
|
||||||
|
|
||||||
let prompt = format!(
|
let prompt = format!(
|
||||||
"\n\n{}int/{}lear/{}uit? ",
|
"\n\n{}int/{}lear/{}ist/{}uit? ",
|
||||||
"h".bold(),
|
"h".bold(),
|
||||||
"c".bold(),
|
"c".bold(),
|
||||||
"q".bold()
|
"l".bold(),
|
||||||
|
"q".bold(),
|
||||||
)
|
)
|
||||||
.into_bytes();
|
.into_bytes();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue