diff options
| author | mo8it <mo8it@proton.me> | 2024-04-07 19:01:08 +0200 |
|---|---|---|
| committer | mo8it <mo8it@proton.me> | 2024-04-07 19:01:08 +0200 |
| commit | 3bd26c7a24a97f9b4b87c453fbdbb06fe9971920 (patch) | |
| tree | b8cd9d7d0f23d69f260d8ec48e721d0c4b858faa /src/state_file.rs | |
| parent | 8c31d38fa17970d0d2dc696922eb8cb329a6fdb9 (diff) | |
State -> StateFile
Diffstat (limited to 'src/state_file.rs')
| -rw-r--r-- | src/state_file.rs | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/src/state_file.rs b/src/state_file.rs new file mode 100644 index 0000000..ca7ed34 --- /dev/null +++ b/src/state_file.rs @@ -0,0 +1,59 @@ +use anyhow::{bail, Context, Result}; +use serde::{Deserialize, Serialize}; +use std::fs; + +use crate::exercise::Exercise; + +#[derive(Serialize, Deserialize)] +pub struct StateFile { + next_exercise_ind: usize, + progress: Vec<bool>, +} + +impl StateFile { + fn read(exercises: &[Exercise]) -> Option<Self> { + let file_content = fs::read(".rustlings.json").ok()?; + + let slf: Self = serde_json::de::from_slice(&file_content).ok()?; + + if slf.progress.len() != exercises.len() || slf.next_exercise_ind >= exercises.len() { + return None; + } + + Some(slf) + } + + pub fn read_or_default(exercises: &[Exercise]) -> Self { + Self::read(exercises).unwrap_or_else(|| Self { + next_exercise_ind: 0, + progress: vec![false; exercises.len()], + }) + } + + fn write(&self) -> Result<()> { + // TODO: Capacity + let mut buf = Vec::with_capacity(1024); + serde_json::ser::to_writer(&mut buf, self).context("Failed to serialize the state")?; + + Ok(()) + } + + #[inline] + pub fn next_exercise_ind(&self) -> usize { + self.next_exercise_ind + } + + pub fn set_next_exercise_ind(&mut self, ind: usize) -> Result<()> { + if ind >= self.progress.len() { + bail!("The next exercise index is higher than the number of exercises"); + } + + self.next_exercise_ind = ind; + self.write() + } + + #[inline] + pub fn progress(&self) -> &[bool] { + &self.progress + } +} |
