geekmagic_common/
config.rs1use std::env;
2use std::fs;
3use std::path::{Path, PathBuf};
4
5use anyhow::{Context, Result};
6use serde::Deserialize;
7
8#[derive(Debug, Default, Deserialize, Clone)]
9pub struct AppConfig {
10 pub host: Option<String>,
11 pub daemon: Option<u64>,
12 pub with_disk: Option<bool>,
13}
14
15fn expand_home(path: &str) -> PathBuf {
16 if path == "~" {
17 return env::var("HOME")
18 .map(PathBuf::from)
19 .unwrap_or_else(|_| PathBuf::from(path));
20 }
21
22 if let Some(rest) = path.strip_prefix("~/") {
23 if let Ok(home) = env::var("HOME") {
24 return PathBuf::from(home).join(rest);
25 }
26 }
27
28 PathBuf::from(path)
29}
30
31pub fn default_config_path() -> PathBuf {
32 let home = env::var("HOME").unwrap_or_else(|_| ".".to_string());
33 PathBuf::from(home)
34 .join(".config")
35 .join("geekmagic-stats")
36 .join("config.toml")
37}
38
39pub fn load(path_override: Option<&str>) -> Result<AppConfig> {
40 let path = path_override
41 .map(expand_home)
42 .unwrap_or_else(default_config_path);
43 load_from_path(&path)
44}
45
46fn load_from_path(path: &Path) -> Result<AppConfig> {
47 if !path.exists() {
48 return Ok(AppConfig::default());
49 }
50
51 let raw = fs::read_to_string(path)
52 .with_context(|| format!("failed to read config at {}", path.display()))?;
53 toml::from_str(&raw).with_context(|| format!("failed to parse config at {}", path.display()))
54}