1use std::fs;
2use std::path::PathBuf;
3
4use anyhow::Context;
5
6use crate::RoadmapState;
7use crate::parser::atomic_write;
8
9#[derive(Debug, Clone)]
10pub struct RoadmapStateStore {
11 data_dir: PathBuf,
12}
13
14impl RoadmapStateStore {
15 pub fn new(data_dir: impl Into<PathBuf>) -> Self {
16 Self {
17 data_dir: data_dir.into(),
18 }
19 }
20
21 pub fn path(&self) -> PathBuf {
22 self.data_dir.join("roadmaps").join("state.json")
23 }
24
25 pub fn load(&self) -> anyhow::Result<Option<RoadmapState>> {
26 let path = self.path();
27 if !path.exists() {
28 return Ok(None);
29 }
30 let bytes = fs::read(&path).with_context(|| format!("read {}", path.display()))?;
31 Ok(Some(serde_json::from_slice(&bytes)?))
32 }
33
34 pub fn save(&self, state: &RoadmapState) -> anyhow::Result<()> {
35 let bytes = serde_json::to_vec_pretty(state)?;
36 atomic_write(&self.path(), &bytes)
37 }
38}