use crate::process::Process;
use anyhow::Result;
use serde::{Deserialize, Serialize};
use std::{collections::BTreeMap, fs, path::PathBuf};
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct Store {
pub next_id: u32,
pub processes: BTreeMap<u32, Process>,
}
impl Store {
pub fn load(path: &PathBuf) -> Self {
if path.exists() {
if let Ok(content) = fs::read_to_string(path) {
if let Ok(store) = serde_json::from_str::<Self>(&content) {
return store;
}
}
}
Self::default()
}
pub fn save(&self, path: &PathBuf) -> Result<()> {
if let Some(parent) = path.parent() {
fs::create_dir_all(parent)?;
}
let tmp_path = path.with_extension("json.tmp");
let content = serde_json::to_string_pretty(self)?;
fs::write(&tmp_path, &content)?;
fs::rename(&tmp_path, path)?;
Ok(())
}
pub fn alloc_id(&mut self) -> u32 {
let id = self.next_id;
self.next_id += 1;
id
}
pub fn find_id(&self, name_or_id: &str) -> Option<u32> {
if let Ok(id) = name_or_id.parse::<u32>() {
if self.processes.contains_key(&id) {
return Some(id);
}
}
self.processes
.values()
.find(|p| p.name == name_or_id)
.map(|p| p.id)
}
pub fn find(&self, name_or_id: &str) -> Option<&Process> {
self.find_id(name_or_id)
.and_then(|id| self.processes.get(&id))
}
}