pm_utils_cli/
storage.rs

1use std::collections::HashMap;
2use std::fs;
3use std::path::Path;
4
5use serde::{Deserialize, Serialize};
6
7#[derive(Debug, Serialize, Deserialize)]
8struct Storage {
9    data: HashMap<String, String>,
10}
11
12pub struct JsonStorage {
13    file_path: String,
14    storage: Storage,
15}
16
17impl JsonStorage {
18    /// Creates a new storage instance, loading from file if it exists
19    pub fn new(file_name: &str) -> anyhow::Result<Self> {
20        let file_path = format!("./{}", file_name);
21        let storage = if Path::new(&file_path).exists() {
22            let content = fs::read_to_string(&file_path)?;
23            serde_json::from_str(&content)?
24        } else {
25            Storage {
26                data: HashMap::new(),
27            }
28        };
29
30        Ok(Self { file_path, storage })
31    }
32
33    /// Creates a new storage file, returns error if it already exists
34    pub fn create(file_name: &str) -> anyhow::Result<Self> {
35        let file_path = format!("./{}", file_name);
36        if Path::new(&file_path).exists() {
37            anyhow::bail!("Storage file already exists");
38        }
39
40        let storage = Storage {
41            data: HashMap::new(),
42        };
43
44        let instance = Self { file_path, storage };
45        instance.save()?;
46
47        Ok(instance)
48    }
49
50    /// Checks if a storage file exists
51    pub fn exists(file_name: &str) -> bool {
52        let file_path = format!("./{}", file_name);
53        Path::new(&file_path).exists()
54    }
55
56    /// Deletes the storage file
57    pub fn delete(&self) -> anyhow::Result<()> {
58        if Path::new(&self.file_path).exists() {
59            fs::remove_file(&self.file_path)?;
60        }
61        Ok(())
62    }
63
64    /// Adds or updates a key-value pair
65    pub fn add_key(&mut self, key: &str, value: &str) -> anyhow::Result<()> {
66        self.storage.data.insert(key.to_string(), value.to_string());
67        self.save()
68    }
69
70    /// Retrieves a value by key
71    pub fn get_key(&self, key: &str) -> Option<&String> {
72        self.storage.data.get(key)
73    }
74
75    /// Saves the current state to file
76    fn save(&self) -> anyhow::Result<()> {
77        let content = serde_json::to_string_pretty(&self.storage)?;
78        fs::write(&self.file_path, content)?;
79        Ok(())
80    }
81}