aboutsummaryrefslogtreecommitdiff
path: root/src/gui/question.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/question.rs')
-rw-r--r--src/gui/question.rs95
1 files changed, 65 insertions, 30 deletions
diff --git a/src/gui/question.rs b/src/gui/question.rs
index abb8fd7..1c44272 100644
--- a/src/gui/question.rs
+++ b/src/gui/question.rs
@@ -29,11 +29,7 @@ pub enum Response {
Answered { difficulty: Difficulty },
}
-pub fn ask<B: Backend>(
- terminal: &mut Terminal<B>,
- title: &str,
- card: &Card,
-) -> Result<Response> {
+pub fn ask<B: Backend>(terminal: &mut Terminal<B>, title: &str, card: &Card) -> Result<Response> {
let mut state = State {
input: String::new(),
answer: Answer::Write,
@@ -81,10 +77,11 @@ pub fn ask<B: Backend>(
.style(match state.answer {
Answer::Write => Style::default(),
Answer::Difficulty { difficulty: _ } => {
- if is_correct(&state.input, &card.responses) {
- Style::default().fg(Color::Green)
- } else {
- Style::default().fg(Color::Red)
+ match check_response(&state.input, &card.responses) {
+ CheckResponse::Correct { phonetics: _ } => {
+ Style::default().fg(Color::Green)
+ }
+ CheckResponse::Incorrect => Style::default().fg(Color::Red),
}
}
})
@@ -97,12 +94,17 @@ pub fn ask<B: Backend>(
difficulty: selected,
} = state.answer
{
- if !is_correct(&state.input, &card.responses) {
- let paragraph = Paragraph::new(util::center_vertically(
- chunks[3],
- &serialization::words_to_line(&card.responses),
- ))
- .alignment(Alignment::Center);
+ let maybe_indication: Option<String> =
+ match check_response(&state.input, &card.responses) {
+ CheckResponse::Correct { phonetics } => phonetics,
+ CheckResponse::Incorrect => {
+ Some(serialization::words_to_line(&card.responses))
+ }
+ };
+
+ if let Some(indication) = maybe_indication {
+ let paragraph = Paragraph::new(util::center_vertically(chunks[3], &indication))
+ .alignment(Alignment::Center);
f.render_widget(paragraph, chunks[3]);
};
@@ -138,10 +140,9 @@ pub fn ask<B: Backend>(
match state.answer {
Answer::Write => match key.code {
KeyCode::Enter => {
- let difficulty = if is_correct(&state.input, &card.responses) {
- Difficulty::Good
- } else {
- Difficulty::Again
+ let difficulty = match check_response(&state.input, &card.responses) {
+ CheckResponse::Correct { phonetics: _ } => Difficulty::Good,
+ CheckResponse::Incorrect => Difficulty::Again,
};
state.answer = Answer::Difficulty { difficulty }
}
@@ -150,7 +151,8 @@ pub fn ask<B: Backend>(
if c == 'u' {
state.input.clear();
} else if c == 'w' {
- let mut words = state.input.split_whitespace().collect::<Vec<&str>>();
+ let mut words =
+ state.input.split_whitespace().collect::<Vec<&str>>();
if !words.is_empty() {
words.truncate(words.len() - 1);
let joined_words = words.join(" ");
@@ -162,7 +164,9 @@ pub fn ask<B: Backend>(
}
} else {
state.input.push(c);
- if is_correct(&state.input, &card.responses) {
+ if let CheckResponse::Correct { phonetics: _ } =
+ check_response(&state.input, &card.responses)
+ {
state.answer = Answer::Difficulty {
difficulty: Difficulty::Good,
}
@@ -205,19 +209,50 @@ pub fn ask<B: Backend>(
}
}
-fn is_correct(input: &str, responses: &[String]) -> bool {
- // Remove whitespaces
- let input = input
+enum CheckResponse {
+ Incorrect,
+ Correct { phonetics: Option<String> },
+}
+
+fn check_response(input: &str, responses: &[String]) -> CheckResponse {
+ let input = remove_whitespaces(input);
+
+ responses
+ .iter()
+ .find(|r| remove_indications_and_phonetics(r) == input)
+ .map(|r| CheckResponse::Correct {
+ phonetics: extract_phonetics(r),
+ })
+ .unwrap_or(CheckResponse::Incorrect)
+}
+
+fn remove_whitespaces(input: &str) -> String {
+ input
.split_whitespace()
.map(|word| word.trim())
.collect::<Vec<&str>>()
- .join(" ");
+ .join(" ")
+}
- responses
- .iter()
- .map(|r| r.split('(').collect::<Vec<&str>>()[0].trim())
- .map(|r| r.split('[').collect::<Vec<&str>>()[0].trim())
- .any(|x| x == input)
+fn remove_indications_and_phonetics(response: &str) -> &str {
+ response
+ .split(|c| c == '(' || c == '[')
+ .collect::<Vec<&str>>()[0]
+ .trim()
+}
+
+fn extract_phonetics(response: &str) -> Option<String> {
+ let s1 = response.split('[').collect::<Vec<&str>>();
+ if s1.len() == 2 {
+ let s2 = s1[1].split(']').collect::<Vec<&str>>();
+ if s2.len() > 1 {
+ Some(format!("[{}]", s2[0]))
+ } else {
+ None
+ }
+ } else {
+ None
+ }
}
fn relative_element<T: Clone + PartialEq>(xs: &[T], x: &T, ri: i32) -> Option<T> {