secrets_cli/
config.rs

1use anyhow::{Context, Result};
2use std::{
3    env::var,
4    fs::{metadata, read_to_string, File},
5    io::Write,
6    path::PathBuf,
7};
8
9#[derive(Debug, PartialEq)]
10pub struct Config {
11    pub config_path: PathBuf,
12    pub secrets_path: PathBuf,
13    pub clipboard_command: String,
14}
15
16impl Config {
17    pub fn create() -> Result<Self> {
18        // Get config path
19        let config_path = var("XDG_CONFIG_HOME")
20            .or_else(|_| var("HOME").map(|v| v + "/.config"))
21            .context("Config not set")?;
22        let mut config_path = PathBuf::from(config_path);
23        config_path.push("secrets-cli.json");
24
25        // If config file doesn't exist, create it
26        if metadata(&config_path).is_err() {
27            let mut file = File::create(&config_path).context("Config file not created")?;
28            file.write_all(b"{\"secrets_path\": \"~/secrets\"}")
29                .context("Config file not written")?;
30            return Ok(Config {
31                config_path,
32                secrets_path: PathBuf::from("~/secrets"),
33                clipboard_command: "xclip".to_string(),
34            });
35        }
36        // If config file exists, read it
37        let config_str = read_to_string(&config_path).context("Config not found")?;
38        let config_json: serde_json::Value =
39            serde_json::from_str(&config_str).context("Config not valid")?;
40        let secrets_path = config_json
41            .get("secrets_path")
42            .and_then(|v| v.as_str())
43            .map(PathBuf::from)
44            .context("Secrets folder path not found in config")?;
45        let clipboard_command = config_json
46            .get("clipboard_command")
47            .and_then(|v| v.as_str())
48            .map(|v| v.to_string())
49            .unwrap_or("xclip".to_string());
50        Ok(Config {
51            config_path,
52            secrets_path,
53            clipboard_command,
54        })
55    }
56}