1use serde::{Deserialize, Serialize};
6use std::fs;
7use std::path::PathBuf;
8
9const SAMPLE_MF4: &[u8] = include_bytes!("../examples/sample.mf4");
11const SAMPLE_DBC: &[u8] = include_bytes!("../examples/sample.dbc");
12
13#[derive(Debug, Clone, Default, Serialize, Deserialize)]
15pub struct SessionConfig {
16 pub dbc_path: Option<String>,
18 pub mdf4_path: Option<String>,
20 #[serde(default)]
22 pub setup_complete: bool,
23}
24
25impl SessionConfig {
26 pub fn config_dir() -> Option<PathBuf> {
28 dirs::config_dir().map(|p| p.join("can-viewer"))
29 }
30
31 pub fn config_path() -> Option<PathBuf> {
33 Self::config_dir().map(|p| p.join("session.json"))
34 }
35
36 pub fn load() -> Self {
38 let mut config: Self = Self::config_path()
40 .and_then(|path| fs::read_to_string(&path).ok())
41 .and_then(|content| serde_json::from_str(&content).ok())
42 .unwrap_or_default();
43
44 if !config.setup_complete {
46 if let Some(config_dir) = Self::config_dir() {
47 if let Err(e) = fs::create_dir_all(&config_dir) {
48 log::warn!("Failed to create config directory: {}", e);
49 }
50
51 let mf4_path = config_dir.join("sample.mf4");
52 let dbc_path = config_dir.join("sample.dbc");
53
54 if let Err(e) = fs::write(&mf4_path, SAMPLE_MF4) {
56 log::warn!("Failed to extract sample MF4: {}", e);
57 }
58 if let Err(e) = fs::write(&dbc_path, SAMPLE_DBC) {
59 log::warn!("Failed to extract sample DBC: {}", e);
60 }
61
62 config.mdf4_path = Some(mf4_path.to_string_lossy().into_owned());
64 config.dbc_path = Some(dbc_path.to_string_lossy().into_owned());
65 config.setup_complete = true;
66 if let Err(e) = config.save() {
67 log::warn!("Failed to save initial config: {}", e);
68 }
69 }
70 }
71
72 config
73 }
74
75 pub fn save(&self) -> Result<(), String> {
77 let path = Self::config_path().ok_or("Could not determine config directory")?;
78
79 if let Some(parent) = path.parent() {
81 fs::create_dir_all(parent)
82 .map_err(|e| format!("Failed to create config directory: {}", e))?;
83 }
84
85 let content = serde_json::to_string_pretty(self)
86 .map_err(|e| format!("Failed to serialize: {}", e))?;
87
88 fs::write(&path, content).map_err(|e| format!("Failed to write config: {}", e))?;
89
90 Ok(())
91 }
92
93 pub fn set_dbc_path(&mut self, path: Option<String>) -> Result<(), String> {
95 self.dbc_path = path;
96 self.save()
97 }
98
99 pub fn set_mdf4_path(&mut self, path: Option<String>) -> Result<(), String> {
101 self.mdf4_path = path;
102 self.save()
103 }
104}