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 let _ = fs::create_dir_all(&config_dir);
48
49 let mf4_path = config_dir.join("sample.mf4");
50 let dbc_path = config_dir.join("sample.dbc");
51
52 let _ = fs::write(&mf4_path, SAMPLE_MF4);
54 let _ = fs::write(&dbc_path, SAMPLE_DBC);
55
56 config.mdf4_path = Some(mf4_path.to_string_lossy().into_owned());
58 config.dbc_path = Some(dbc_path.to_string_lossy().into_owned());
59 config.setup_complete = true;
60 let _ = config.save();
61 }
62 }
63
64 config
65 }
66
67 pub fn save(&self) -> Result<(), String> {
69 let path = Self::config_path().ok_or("Could not determine config directory")?;
70
71 if let Some(parent) = path.parent() {
73 fs::create_dir_all(parent)
74 .map_err(|e| format!("Failed to create config directory: {}", e))?;
75 }
76
77 let content = serde_json::to_string_pretty(self)
78 .map_err(|e| format!("Failed to serialize: {}", e))?;
79
80 fs::write(&path, content).map_err(|e| format!("Failed to write config: {}", e))?;
81
82 Ok(())
83 }
84
85 pub fn set_dbc_path(&mut self, path: Option<String>) -> Result<(), String> {
87 self.dbc_path = path;
88 self.save()
89 }
90
91 pub fn set_mdf4_path(&mut self, path: Option<String>) -> Result<(), String> {
93 self.mdf4_path = path;
94 self.save()
95 }
96}