1use serde::{Deserialize, Serialize};
4use std::fs;
5use std::path::{Path, PathBuf};
6use tracing::debug;
7
8pub struct StateStore {
10 path: PathBuf,
11}
12
13impl StateStore {
14 pub fn new<P: AsRef<Path>>(dir: P) -> Self {
16 let path = dir.as_ref().join("state.json");
17 Self { path }
18 }
19
20 pub fn load<T>(&self) -> anyhow::Result<Option<T>>
22 where
23 T: for<'de> Deserialize<'de>,
24 {
25 if !self.path.exists() {
26 return Ok(None);
27 }
28
29 let data = fs::read_to_string(&self.path)?;
30 let state = serde_json::from_str(&data)?;
31 debug!("Loaded state from {:?}", self.path);
32 Ok(Some(state))
33 }
34
35 pub fn save<T>(&self, state: &T) -> anyhow::Result<()>
37 where
38 T: Serialize,
39 {
40 if let Some(parent) = self.path.parent() {
41 fs::create_dir_all(parent)?;
42 }
43
44 let data = serde_json::to_string_pretty(state)?;
45 fs::write(&self.path, data)?;
46 debug!("Saved state to {:?}", self.path);
47 Ok(())
48 }
49}