diff options
| author | Miquel Sabaté Solà <mikisabate@gmail.com> | 2025-07-29 21:55:31 +0200 |
|---|---|---|
| committer | Miquel Sabaté Solà <mikisabate@gmail.com> | 2025-07-29 21:58:02 +0200 |
| commit | 7b7faf70dbdd83020b4bf6f9c3242a994c97665a (patch) | |
| tree | b4adb273557507ee882c235bddcc11425ebf1e46 /lib | |
| parent | b25f575e41f078be3e47d843fda1827881f23646 (diff) | |
| download | mihi-7b7faf70dbdd83020b4bf6f9c3242a994c97665a.tar.gz mihi-7b7faf70dbdd83020b4bf6f9c3242a994c97665a.zip | |
Add exercises to the practice command
The '-e/--exercises' has also been introduced to instruct the 'practice'
command to only go for exercises, and the '-k/--kind' flag allows the
user to further filter which kind of exercise to practice.
Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/mihi/src/lib.rs | 66 |
1 files changed, 65 insertions, 1 deletions
diff --git a/lib/mihi/src/lib.rs b/lib/mihi/src/lib.rs index 7d5cc8c..7d13226 100644 --- a/lib/mihi/src/lib.rs +++ b/lib/mihi/src/lib.rs @@ -563,7 +563,21 @@ impl TryFrom<usize> for ExerciseKind { 1 => Ok(Self::Translation), 2 => Ok(Self::Transformation), 3 => Ok(Self::Numerical), - _ => Err("unknonwn kind!"), + _ => Err("unknonwn exercise kind"), + } + } +} + +impl TryFrom<&str> for ExerciseKind { + type Error = &'static str; + + fn try_from(value: &str) -> Result<Self, Self::Error> { + match value { + "pensum" => Ok(Self::Pensum), + "translation" => Ok(Self::Translation), + "transformation" => Ok(Self::Transformation), + "numerical" => Ok(Self::Numerical), + _ => Err("unknonwn exercise kind. Available: pensum, translation, transformation and numerical"), } } } @@ -689,3 +703,53 @@ pub fn delete_exercise(title: &str) -> Result<(), String> { Err(e) => Err(format!("could not remove '{title}': {e}")), } } + +// Get a list of exercises sorted by relevance. A maximum of `limit` exercises +// will be returned, and you can also specify to filter the returned exercises +// by `kind`. +pub fn select_relevant_exercises( + kind: Option<ExerciseKind>, + limit: usize, +) -> Result<Vec<Exercise>, String> { + let conn = get_connection()?; + + let mut stmt; + let mut it = match kind { + Some(kind) => { + stmt = conn + .prepare( + "SELECT id, title, enunciate, solution, lessons, kind \ + FROM exercises \ + WHERE kind = ?1 \ + ORDER BY updated_at DESC \ + LIMIT ?2", + ) + .unwrap(); + stmt.query([kind as usize, limit]).unwrap() + } + None => { + stmt = conn + .prepare( + "SELECT id, title, enunciate, solution, lessons, kind \ + FROM exercises \ + ORDER BY updated_at DESC \ + LIMIT ?1", + ) + .unwrap(); + stmt.query([limit]).unwrap() + } + }; + + let mut res = vec![]; + while let Some(row) = it.next().unwrap() { + res.push(Exercise { + id: row.get(0).unwrap(), + title: row.get(1).unwrap(), + enunciate: row.get(2).unwrap(), + solution: row.get(3).unwrap(), + lessons: row.get(4).unwrap(), + kind: row.get::<usize, usize>(5).unwrap().try_into()?, + }); + } + Ok(res) +} |
