Skip to main content

ipp_printer_app/
state.rs

1//! Persisted printer list (JSON).
2
3use std::fs;
4use std::path::{Path, PathBuf};
5
6use serde::{Deserialize, Serialize};
7
8use crate::printer::PrinterConfig;
9
10/// What the framework persists between runs — just the registered printers.
11#[derive(Debug, Clone, Serialize, Deserialize, Default)]
12#[allow(missing_docs)]
13pub struct PersistedState {
14    pub printers: Vec<PrinterConfig>,
15}
16
17impl PersistedState {
18    /// Read from `path`. Missing / unparseable file → empty state (no error).
19    pub fn load(path: &Path) -> Self {
20        match fs::read_to_string(path) {
21            Ok(s) => serde_json::from_str(&s).unwrap_or_default(),
22            Err(_) => PersistedState::default(),
23        }
24    }
25
26    /// Write to `path` as pretty JSON. Creates parent dirs.
27    pub fn save(&self, path: &Path) -> std::io::Result<()> {
28        if let Some(parent) = path.parent() {
29            fs::create_dir_all(parent)?;
30        }
31        let json = serde_json::to_string_pretty(self)?;
32        fs::write(path, json)
33    }
34}
35
36/// Application state path: `$XDG_STATE_HOME/<app_id>.state.json`,
37/// falling back to `$HOME/.local/state/<app_id>.state.json`.
38pub fn default_state_path(app_id: &str) -> PathBuf {
39    if let Ok(dir) = std::env::var("XDG_STATE_HOME") {
40        if !dir.is_empty() {
41            return PathBuf::from(format!("{dir}/{app_id}.state.json"));
42        }
43    }
44    let home = std::env::var("HOME").unwrap_or_else(|_| "/tmp".into());
45    PathBuf::from(format!("{home}/.local/state/{app_id}.state.json"))
46}