trailcache_core/
config.rs1use std::path::PathBuf;
9
10use anyhow::Result;
11use serde::{Deserialize, Serialize};
12
13const APP_NAME: &str = "trailcache";
15
16const CONFIG_FILE: &str = "config.json";
18
19#[derive(Debug, Clone, Serialize, Deserialize, Default)]
20pub struct Config {
21 pub organization_guid: Option<String>,
22 pub unit_name: Option<String>,
23 pub last_username: Option<String>,
24 #[serde(default)]
25 pub offline_mode: bool,
26 #[serde(skip)]
28 pub config_dir_override: Option<PathBuf>,
29 #[serde(skip)]
31 pub cache_dir_override: Option<PathBuf>,
32}
33
34impl Config {
35 pub fn load() -> Result<Self> {
36 let path = Self::config_path()?;
37 if path.exists() {
38 let contents = std::fs::read_to_string(&path)?;
39 Ok(serde_json::from_str(&contents)?)
40 } else {
41 Ok(Self::default())
42 }
43 }
44
45 pub fn load_from(config_dir: PathBuf) -> Result<Self> {
47 let path = config_dir.join(APP_NAME).join(CONFIG_FILE);
48 if path.exists() {
49 let contents = std::fs::read_to_string(&path)?;
50 let mut config: Config = serde_json::from_str(&contents)?;
51 config.config_dir_override = Some(config_dir);
52 Ok(config)
53 } else {
54 Ok(Self {
55 config_dir_override: Some(config_dir),
56 ..Self::default()
57 })
58 }
59 }
60
61 pub fn save(&self) -> Result<()> {
62 let path = self.resolved_config_path()?;
63 if let Some(parent) = path.parent() {
64 std::fs::create_dir_all(parent)?;
65 }
66 let contents = serde_json::to_string_pretty(self)?;
67 std::fs::write(path, contents)?;
68 Ok(())
69 }
70
71 fn config_path() -> Result<PathBuf> {
72 let config_dir = dirs::config_dir()
73 .ok_or_else(|| anyhow::anyhow!("Could not find config directory"))?;
74 Ok(config_dir.join(APP_NAME).join(CONFIG_FILE))
75 }
76
77 fn resolved_config_path(&self) -> Result<PathBuf> {
78 if let Some(ref dir) = self.config_dir_override {
79 Ok(dir.join(APP_NAME).join(CONFIG_FILE))
80 } else {
81 Self::config_path()
82 }
83 }
84
85 pub fn cache_dir(&self) -> Result<PathBuf> {
86 let base = if let Some(ref dir) = self.cache_dir_override {
87 dir.clone()
88 } else {
89 dirs::cache_dir()
90 .ok_or_else(|| anyhow::anyhow!("Could not find cache directory"))?
91 };
92
93 let mut path = base.join(APP_NAME);
94 if let Some(ref org) = self.organization_guid {
95 path = path.join(org);
96 }
97 Ok(path)
98 }
99
100 pub fn set_cache_dir(&mut self, dir: PathBuf) {
102 self.cache_dir_override = Some(dir);
103 }
104}