1use std::fs;
2use std::path::PathBuf;
3
4use anyhow::Context;
5use directories::BaseDirs;
6use serde::{Deserialize, Serialize};
7
8use crate::error::Result;
9
10const CONFIG_FILE: &str = "config.toml";
11const CATALOG_FILE: &str = "themes.toml";
12
13#[derive(Debug, Default, Serialize, Deserialize)]
14pub struct Config {
15 #[serde(default)]
16 pub current_theme: Option<String>,
17}
18
19pub struct Paths {
20 pub home: PathBuf,
21 pub root: PathBuf,
22 pub config: PathBuf,
23 pub catalog: PathBuf,
24}
25
26impl Paths {
27 pub fn new() -> Result<Self> {
28 let home = BaseDirs::new()
29 .context("could not determine the user home directory")?
30 .home_dir()
31 .to_path_buf();
32
33 let root = home.join(".config/hue");
34
35 Ok(Self {
36 home,
37 config: root.join(CONFIG_FILE),
38 catalog: root.join(CATALOG_FILE),
39 root,
40 })
41 }
42}
43
44pub fn init_config(paths: &Paths) -> Result<()> {
45 if paths.config.exists() {
46 return Ok(());
47 }
48
49 fs::create_dir_all(&paths.root)?;
50
51 let config = Config::default();
52 save_config(paths, &config)?;
53
54 Ok(())
55}
56
57pub fn load_config(paths: &Paths) -> Result<Config> {
58 init_config(paths)?;
59
60 let config_str = fs::read_to_string(&paths.config)?;
61 let config_toml = toml::from_str(&config_str)?;
62
63 Ok(config_toml)
64}
65
66pub fn save_config(paths: &Paths, config: &Config) -> Result<()> {
67 let config_str = toml::to_string_pretty(config)?;
68
69 fs::write(&paths.config, config_str)?;
70
71 Ok(())
72}