netrunner_core/
settings.rs1use serde::{Deserialize, Serialize};
8use std::path::PathBuf;
9
10use crate::types::{DetailLevel, TestConfig};
11
12#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
17#[serde(default)]
18pub struct Settings {
19 pub server_url: String,
21 pub test_size_mb: u64,
23 pub timeout_seconds: u64,
25 pub detail_level: DetailLevel,
27 pub animations: bool,
29 pub auto_run: bool,
31 pub max_history: usize,
33}
34
35impl Default for Settings {
36 fn default() -> Self {
37 let cfg = TestConfig::default();
38 Self {
39 server_url: cfg.server_url,
40 test_size_mb: cfg.test_size_mb,
41 timeout_seconds: cfg.timeout_seconds,
42 detail_level: cfg.detail_level,
43 animations: cfg.animation_enabled,
44 auto_run: true,
45 max_history: 20,
46 }
47 }
48}
49
50impl Settings {
51 pub fn config_path() -> Result<PathBuf, Box<dyn std::error::Error>> {
53 let dir = dirs::config_dir()
54 .ok_or("Failed to find config directory")?
55 .join("netrunner");
56 std::fs::create_dir_all(&dir)?;
57 Ok(dir.join("settings.json"))
58 }
59
60 pub fn load() -> Self {
63 Self::config_path()
64 .ok()
65 .and_then(|p| std::fs::read_to_string(p).ok())
66 .and_then(|s| serde_json::from_str(&s).ok())
67 .unwrap_or_default()
68 }
69
70 pub fn save(&self) -> Result<(), Box<dyn std::error::Error>> {
72 let path = Self::config_path()?;
73 std::fs::write(path, serde_json::to_string_pretty(self)?)?;
74 Ok(())
75 }
76
77 pub fn to_config(&self) -> TestConfig {
79 TestConfig {
80 server_url: self.server_url.clone(),
81 test_size_mb: self.test_size_mb,
82 timeout_seconds: self.timeout_seconds,
83 json_output: false,
84 animation_enabled: self.animations,
85 detail_level: self.detail_level,
86 max_servers: 3,
87 }
88 }
89}
90
91#[cfg(test)]
92mod tests {
93 use super::*;
94
95 #[test]
96 fn default_matches_test_config() {
97 let s = Settings::default();
98 let c = s.to_config();
99 assert_eq!(c.server_url, TestConfig::default().server_url);
100 assert_eq!(c.test_size_mb, 10);
101 assert!(s.auto_run);
102 assert_eq!(s.max_history, 20);
103 }
104
105 #[test]
106 fn json_roundtrip() {
107 let s = Settings {
108 timeout_seconds: 42,
109 auto_run: false,
110 ..Default::default()
111 };
112 let json = serde_json::to_string_pretty(&s).unwrap();
113 let back: Settings = serde_json::from_str(&json).unwrap();
114 assert_eq!(s, back);
115 }
116
117 #[test]
118 fn partial_json_uses_defaults() {
119 let back: Settings = serde_json::from_str(r#"{ "timeout_seconds": 99 }"#).unwrap();
121 assert_eq!(back.timeout_seconds, 99);
122 assert_eq!(back.test_size_mb, Settings::default().test_size_mb);
123 assert!(back.auto_run);
124 }
125}