use serde::{Deserialize, Serialize}; use std::{fs, path::PathBuf, sync::RwLock}; use tauri::{path::BaseDirectory, AppHandle, Manager}; #[derive(Clone, Deserialize, Serialize)] pub enum ProxyKind { Http, Socks5, } impl Default for ProxyKind { fn default() -> Self { Self::Http } } #[derive(Clone, Deserialize, Serialize, Default)] #[serde(rename_all = "camelCase")] pub struct ProxyConfig { pub enabled: bool, pub kind: ProxyKind, pub host: Option, pub port: Option, pub username: Option, pub password: Option, } #[derive(Clone, Deserialize, Serialize, Default)] #[serde(rename_all = "camelCase")] pub struct AppConfig { pub proxy: Option, } pub struct AppConfigState { inner: RwLock, } impl AppConfigState { pub fn new(config: AppConfig) -> Self { Self { inner: RwLock::new(config), } } pub fn get(&self) -> anyhow::Result { let guard = self .inner .read() .map_err(|_| anyhow::anyhow!("读取应用配置状态失败"))?; Ok(guard.clone()) } pub fn set(&self, config: AppConfig) -> anyhow::Result<()> { let mut guard = self .inner .write() .map_err(|_| anyhow::anyhow!("写入应用配置状态失败"))?; *guard = config; Ok(()) } } impl AppConfig { fn config_path(app_handle: &AppHandle) -> anyhow::Result { Ok(app_handle .path() .resolve("config.json", BaseDirectory::AppData)?) } pub fn save(&self, app_handle: &AppHandle) -> anyhow::Result<()> { let config_path = Self::config_path(app_handle)?; if let Some(parent_dir) = config_path.parent() { fs::create_dir_all(parent_dir)?; } let content = serde_json::to_string_pretty(self)?; fs::write(config_path, content)?; Ok(()) } pub fn load(app_handle: &AppHandle) -> anyhow::Result { let config_path = Self::config_path(app_handle)?; if !config_path.exists() { return Ok(Self::default()); } let content = fs::read_to_string(config_path)?; Ok(serde_json::from_str(&content)?) } pub fn load_or_init(app_handle: &AppHandle) -> anyhow::Result { let config_path = Self::config_path(app_handle)?; if !config_path.exists() { let default_config = Self::default(); default_config.save(app_handle)?; return Ok(default_config); } Self::load(app_handle) } }