diff --git a/src/main.rs b/src/main.rs index b2d5eaa..96542da 100644 --- a/src/main.rs +++ b/src/main.rs @@ -49,6 +49,10 @@ pub struct Cli { /// language to pull words from #[clap(short = 'l', long, arg_enum, default_value_t = SupportedLanguage::English)] supported_language: SupportedLanguage, + + /// is death mode enabled + #[clap(short = 'd', long = "death-mode")] + death_mode: bool, } #[derive(Debug, Copy, Clone, ArgEnum, strum_macros::Display)] @@ -88,7 +92,7 @@ impl App { }; if cli.number_of_sentences.is_some() { Self { - thok: Thok::new(prompt, count, cli.number_of_secs.map(|ns| ns as f64)), + thok: Thok::new(prompt, count, cli.number_of_secs.map(|ns| ns as f64), cli.death_mode), cli: Some(cli), } } else { @@ -97,6 +101,7 @@ impl App { prompt, cli.number_of_words, cli.number_of_secs.map(|ns| ns as f64), + cli.death_mode, ), cli: Some(cli), } @@ -123,12 +128,13 @@ impl App { }, }; if cli.number_of_sentences.is_some() { - self.thok = Thok::new(prompt, count, cli.number_of_secs.map(|ns| ns as f64)); + self.thok = Thok::new(prompt, count, cli.number_of_secs.map(|ns| ns as f64), cli.death_mode); } else { self.thok = Thok::new( prompt, cli.number_of_words, cli.number_of_secs.map(|ns| ns as f64), + cli.death_mode, ); } } diff --git a/src/thok.rs b/src/thok.rs index c7ec39e..bdc3724 100644 --- a/src/thok.rs +++ b/src/thok.rs @@ -32,13 +32,19 @@ pub struct Thok { pub seconds_remaining: Option, pub number_of_secs: Option, pub number_of_words: usize, + pub death_mode: bool, pub wpm: f64, pub accuracy: f64, pub std_dev: f64, } impl Thok { - pub fn new(prompt: String, number_of_words: usize, number_of_secs: Option) -> Self { + pub fn new( + prompt: String, + number_of_words: usize, + number_of_secs: Option, + death_mode: bool, + ) -> Self { Self { prompt, input: vec![], @@ -48,6 +54,7 @@ impl Thok { started_at: None, number_of_secs, number_of_words, + death_mode, seconds_remaining: number_of_secs, wpm: 0.0, accuracy: 0.0, @@ -189,8 +196,17 @@ impl Thok { } pub fn has_finished(&self) -> bool { - (self.input.len() == self.prompt.len()) - || (self.seconds_remaining.is_some() && self.seconds_remaining.unwrap() <= 0.0) + let finished_prompt = self.input.len() == self.prompt.len(); + let out_of_time = + self.seconds_remaining.is_some() && self.seconds_remaining.unwrap() <= 0.0; + let is_fatal_error = self.death_mode + && self + .input + .clone() + .into_iter() + .any(|i| i.outcome == Outcome::Incorrect); + + finished_prompt || out_of_time || is_fatal_error } pub fn save_results(&self) -> io::Result<()> { diff --git a/src/ui.rs b/src/ui.rs index bdac4a7..8803a9a 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -135,7 +135,7 @@ impl Widget for &Thok { for ts in &self.wpm_coords { if ts.1 > highest_wpm { - highest_wpm = ts.1 as f64; + highest_wpm = ts.1; } } @@ -178,11 +178,22 @@ impl Widget for &Thok { chart.render(chunks[0], buf); + let bad_death = self.death_mode + && self + .input + .clone() + .into_iter() + .any(|i| i.outcome == Outcome::Incorrect); + let stats = Paragraph::new(Span::styled( - format!( - "{} wpm {}% acc {:.2} sd", - self.wpm, self.accuracy, self.std_dev - ), + if bad_death { + format!("💀") + } else { + format!( + "{} wpm {}% acc {:.2} sd", + self.wpm, self.accuracy, self.std_dev + ) + }, bold_style, )) .alignment(Alignment::Center);