//! CLI configuration. use std::fs; use std::path::{Path, PathBuf}; use serde::{Deserialize, Serialize}; /// CLI configuration. #[derive(Clone, Debug, Serialize, Deserialize)] pub struct CliConfig { /// RPC server URL. pub rpc_url: String, /// Default wallet name. pub default_wallet: String, /// Wallet directory. pub wallet_dir: PathBuf, /// Network (mainnet, testnet, devnet). pub network: String, /// Default output format. pub output_format: String, } impl Default for CliConfig { fn default() -> Self { CliConfig { rpc_url: "http://127.0.0.1:16110".to_string(), default_wallet: "default".to_string(), wallet_dir: default_wallet_dir(), network: "mainnet".to_string(), output_format: "text".to_string(), } } } impl CliConfig { /// Loads config from file or returns default. pub fn load_or_default(path: Option<&Path>) -> Self { if let Some(p) = path { Self::load(p).unwrap_or_default() } else if let Some(default_path) = default_config_path() { Self::load(&default_path).unwrap_or_default() } else { Self::default() } } /// Loads config from file. pub fn load(path: &Path) -> anyhow::Result { let content = fs::read_to_string(path)?; let config: CliConfig = toml::from_str(&content)?; Ok(config) } /// Saves config to file. pub fn save(&self, path: &Path) -> anyhow::Result<()> { let content = toml::to_string_pretty(self)?; if let Some(parent) = path.parent() { fs::create_dir_all(parent)?; } fs::write(path, content)?; Ok(()) } /// Gets wallet file path. pub fn wallet_path(&self, name: &str) -> PathBuf { self.wallet_dir.join(format!("{}.wallet", name)) } /// Gets default wallet path. pub fn default_wallet_path(&self) -> PathBuf { self.wallet_path(&self.default_wallet) } } /// Gets default config directory. pub fn default_config_dir() -> Option { dirs::config_dir().map(|d| d.join("synor")) } /// Gets default config path. pub fn default_config_path() -> Option { default_config_dir().map(|d| d.join("cli.toml")) } /// Gets default wallet directory. pub fn default_wallet_dir() -> PathBuf { dirs::data_dir() .unwrap_or_else(|| PathBuf::from(".")) .join("synor") .join("wallets") } #[cfg(test)] mod tests { use super::*; use tempfile::tempdir; #[test] fn test_config_save_load() { let dir = tempdir().unwrap(); let path = dir.path().join("config.toml"); let config = CliConfig::default(); config.save(&path).unwrap(); let loaded = CliConfig::load(&path).unwrap(); assert_eq!(loaded.rpc_url, config.rpc_url); } }