Skip to main content

tar_install/
state.rs

1use crate::paths::InstallScope;
2use anyhow::{Context, Result};
3use serde::{Deserialize, Serialize};
4use std::collections::BTreeMap;
5use std::fs;
6use std::path::{Path, PathBuf};
7
8#[derive(Debug, Clone, Serialize, Deserialize)]
9pub struct InstalledApp {
10    pub id: String,
11    pub name: String,
12    pub version: Option<String>,
13    pub scope: InstallScope,
14    pub install_dir: PathBuf,
15    pub command_name: String,
16    pub command_path: PathBuf,
17    pub desktop_path: PathBuf,
18    pub icon_paths: Vec<PathBuf>,
19    pub source_archive: Option<PathBuf>,
20    pub source_sha256: Option<String>,
21}
22
23#[derive(Debug, Clone, Default, Serialize, Deserialize)]
24pub struct StateDb {
25    pub apps: BTreeMap<String, InstalledApp>,
26}
27
28pub fn load_state(path: &Path) -> Result<StateDb> {
29    if !path.exists() {
30        return Ok(StateDb::default());
31    }
32    let text = fs::read_to_string(path).with_context(|| format!("failed to read state DB: {}", path.display()))?;
33    let db = serde_json::from_str(&text).with_context(|| format!("failed to parse state DB: {}", path.display()))?;
34    Ok(db)
35}
36
37pub fn save_state(path: &Path, db: &StateDb) -> Result<()> {
38    if let Some(parent) = path.parent() {
39        fs::create_dir_all(parent).with_context(|| format!("failed to create state dir: {}", parent.display()))?;
40    }
41    let text = serde_json::to_string_pretty(db)?;
42    fs::write(path, text).with_context(|| format!("failed to write state DB: {}", path.display()))?;
43    Ok(())
44}