use serde::{Deserialize, Serialize};
use std::path::PathBuf;
use crate::types::{DetailLevel, TestConfig};
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(default)]
pub struct Settings {
pub server_url: String,
pub test_size_mb: u64,
pub timeout_seconds: u64,
pub detail_level: DetailLevel,
pub animations: bool,
pub auto_run: bool,
pub max_history: usize,
}
impl Default for Settings {
fn default() -> Self {
let cfg = TestConfig::default();
Self {
server_url: cfg.server_url,
test_size_mb: cfg.test_size_mb,
timeout_seconds: cfg.timeout_seconds,
detail_level: cfg.detail_level,
animations: cfg.animation_enabled,
auto_run: true,
max_history: 20,
}
}
}
impl Settings {
pub fn config_path() -> Result<PathBuf, Box<dyn std::error::Error>> {
let dir = dirs::config_dir()
.ok_or("Failed to find config directory")?
.join("netrunner");
std::fs::create_dir_all(&dir)?;
Ok(dir.join("settings.json"))
}
pub fn load() -> Self {
Self::config_path()
.ok()
.and_then(|p| std::fs::read_to_string(p).ok())
.and_then(|s| serde_json::from_str(&s).ok())
.unwrap_or_default()
}
pub fn save(&self) -> Result<(), Box<dyn std::error::Error>> {
let path = Self::config_path()?;
std::fs::write(path, serde_json::to_string_pretty(self)?)?;
Ok(())
}
pub fn to_config(&self) -> TestConfig {
TestConfig {
server_url: self.server_url.clone(),
test_size_mb: self.test_size_mb,
timeout_seconds: self.timeout_seconds,
json_output: false,
animation_enabled: self.animations,
detail_level: self.detail_level,
max_servers: 3,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn default_matches_test_config() {
let s = Settings::default();
let c = s.to_config();
assert_eq!(c.server_url, TestConfig::default().server_url);
assert_eq!(c.test_size_mb, 10);
assert!(s.auto_run);
assert_eq!(s.max_history, 20);
}
#[test]
fn json_roundtrip() {
let s = Settings {
timeout_seconds: 42,
auto_run: false,
..Default::default()
};
let json = serde_json::to_string_pretty(&s).unwrap();
let back: Settings = serde_json::from_str(&json).unwrap();
assert_eq!(s, back);
}
#[test]
fn partial_json_uses_defaults() {
let back: Settings = serde_json::from_str(r#"{ "timeout_seconds": 99 }"#).unwrap();
assert_eq!(back.timeout_seconds, 99);
assert_eq!(back.test_size_mb, Settings::default().test_size_mb);
assert!(back.auto_run);
}
}