ssr_algorithms/leitner_system/
mod.rs

1use level::Level;
2use s_text_input_f::BlocksWithAnswer;
3use serde::{Deserialize, Serialize};
4use ssr_core::task::{level::TaskLevel, Task};
5use std::time::SystemTime;
6
7mod level;
8
9#[derive(Serialize, Deserialize)]
10pub struct WriteAnswer {
11    level: Level,
12    input_blocks: s_text_input_f::Blocks,
13    correct_answer: s_text_input_f::Response,
14}
15
16impl WriteAnswer {
17    pub fn new(
18        input_blocks: s_text_input_f::Blocks,
19        correct_answer: s_text_input_f::Response,
20    ) -> Self {
21        Self {
22            level: Default::default(),
23            input_blocks,
24            correct_answer,
25        }
26    }
27}
28
29impl Task<'_> for WriteAnswer {
30    type SharedState = ();
31
32    fn next_repetition(&self, shared: &(), _: f64) -> SystemTime {
33        self.level.next_repetition(shared, 0.)
34    }
35
36    fn complete(
37        &mut self,
38        _: &mut (),
39        _desired_retention: f64,
40        interaction: &mut impl FnMut(
41            s_text_input_f::Blocks,
42        ) -> std::io::Result<s_text_input_f::Response>,
43    ) -> std::io::Result<()> {
44        let user_answer = interaction(self.input_blocks.clone())?;
45        match s_text_input_f::eq_response(&user_answer, &self.correct_answer, true, false) {
46            false => {
47                let mut feedback = s_text_input_f::to_answered(
48                    self.input_blocks.clone(),
49                    user_answer,
50                    self.correct_answer.clone(),
51                )
52                .into_iter()
53                .map(s_text_input_f::Block::Answered)
54                .collect::<Vec<_>>();
55                feedback.push(s_text_input_f::Block::Paragraph(vec![]));
56                feedback.push(s_text_input_f::Block::OneOf(vec!["OK".to_string()]));
57                interaction(feedback)?;
58                self.level.update(&mut (), (SystemTime::now(), false));
59            }
60            true => {
61                let feedback = vec![
62                    s_text_input_f::Block::Paragraph(vec![s_text_input_f::ParagraphItem::Text(
63                        "All answers correct!".to_string(),
64                    )]),
65                    s_text_input_f::Block::OneOf(vec!["OK".to_string()]),
66                ];
67                interaction(feedback)?;
68                self.level.update(&mut (), (SystemTime::now(), true));
69            }
70        }
71        Ok(())
72    }
73
74    fn new(input: s_text_input_f::BlocksWithAnswer) -> Self {
75        Self {
76            level: Default::default(),
77            input_blocks: input.blocks,
78            correct_answer: input.answer,
79        }
80    }
81
82    fn get_blocks(&self) -> s_text_input_f::BlocksWithAnswer {
83        BlocksWithAnswer {
84            blocks: self.input_blocks.clone(),
85            answer: self.correct_answer.clone(),
86        }
87    }
88}