1use std::path::PathBuf;
2
3use directories::ProjectDirs;
4use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Serialize, Deserialize)]
10pub struct Config {
11 #[serde(default = "default_shell_cmd")]
12 pub shell_cmd: String,
13 #[serde(default = "default_scan_depth")]
14 pub scan_depth: usize,
15 pub database_path: Option<PathBuf>,
16}
17
18fn default_shell_cmd() -> String {
19 "prjp".to_string()
20}
21
22fn default_scan_depth() -> usize {
23 3
24}
25
26impl Default for Config {
27 fn default() -> Self {
28 Self {
29 shell_cmd: default_shell_cmd(),
30 scan_depth: default_scan_depth(),
31 database_path: None,
32 }
33 }
34}
35
36impl Config {
37 pub fn load() -> color_eyre::Result<Self> {
38 let config_path = Self::config_path();
39 if config_path.exists() {
40 let content = std::fs::read_to_string(&config_path)?;
41 Ok(toml::from_str(&content)?)
42 } else {
43 Ok(Self::default())
44 }
45 }
46
47 pub fn config_path() -> PathBuf {
48 Self::project_dirs().config_dir().join("config.toml")
49 }
50
51 pub fn database_path(&self) -> PathBuf {
52 self.database_path
53 .clone()
54 .unwrap_or_else(|| Self::project_dirs().data_dir().join("projects.toml"))
55 }
56
57 fn project_dirs() -> ProjectDirs {
58 ProjectDirs::from("", "", "prj").expect("could not determine project directories")
59 }
60}