Kaynağa Gözat

feat(desktop-pet): 设置文件读写与默认值

liaoxg 2 gün önce
ebeveyn
işleme
4447df043b

+ 1 - 0
cfc-desktop-pet/src-tauri/src/main.rs

@@ -2,6 +2,7 @@
 
 mod api;
 mod config;
+mod settings;
 mod state;
 mod token;
 

+ 91 - 0
cfc-desktop-pet/src-tauri/src/settings.rs

@@ -0,0 +1,91 @@
+use serde::{Deserialize, Serialize};
+use std::fs;
+use std::path::PathBuf;
+
+#[derive(Debug, Clone, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct AppSettings {
+    #[serde(default = "default_base_url")]
+    pub base_url: String,
+}
+
+impl Default for AppSettings {
+    fn default() -> Self {
+        Self { base_url: default_base_url() }
+    }
+}
+
+fn default_base_url() -> String {
+    "http://localhost:9082".to_string()
+}
+
+pub struct SettingsStore {
+    path: PathBuf,
+}
+
+impl SettingsStore {
+    pub fn new(app_config_dir: PathBuf) -> Self {
+        Self { path: app_config_dir.join("settings.json") }
+    }
+
+    pub fn load(&self) -> AppSettings {
+        match fs::read_to_string(&self.path) {
+            Ok(txt) => serde_json::from_str(&txt).unwrap_or_default(),
+            Err(_) => AppSettings::default(),
+        }
+    }
+
+    pub fn save(&self, s: &AppSettings) -> Result<(), String> {
+        if let Some(dir) = self.path.parent() {
+            fs::create_dir_all(dir).map_err(|e| e.to_string())?;
+        }
+        let txt = serde_json::to_string_pretty(s).map_err(|e| e.to_string())?;
+        fs::write(&self.path, txt).map_err(|e| e.to_string())
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use std::fs;
+    use std::sync::atomic::{AtomicUsize, Ordering};
+
+    static COUNTER: AtomicUsize = AtomicUsize::new(0);
+
+    fn temp_dir() -> std::path::PathBuf {
+        let n = COUNTER.fetch_add(1, Ordering::SeqCst);
+        let dir = std::env::temp_dir().join(format!("xafpet-settings-test-{}", n));
+        let _ = fs::remove_dir_all(&dir);
+        dir
+    }
+
+    #[test]
+    fn default_when_file_missing() {
+        let store = SettingsStore::new(temp_dir());
+        let cfg = store.load();
+        assert_eq!(cfg.base_url, "http://localhost:9082");
+    }
+
+    #[test]
+    fn default_when_file_malformed() {
+        let dir = temp_dir();
+        fs::create_dir_all(&dir).unwrap();
+        fs::write(dir.join("settings.json"), "not json").unwrap();
+        let store = SettingsStore::new(dir);
+        let cfg = store.load();
+        assert_eq!(cfg.base_url, "http://localhost:9082");
+    }
+
+    #[test]
+    fn roundtrip_save_load() {
+        let dir = temp_dir();
+        let store = SettingsStore::new(dir.clone());
+        let mut cfg = store.load();
+        cfg.base_url = "http://192.168.1.5:9082".into();
+        store.save(&cfg).unwrap();
+
+        let store2 = SettingsStore::new(dir.clone());
+        assert_eq!(store2.load().base_url, "http://192.168.1.5:9082");
+        let _ = fs::remove_dir_all(&dir);
+    }
+}