fluere_config/
init.rs

1use std::{default::Default, env, fs, path::Path, path::PathBuf};
2
3use crate::Config;
4
5use dirs::config_dir;
6
7#[cfg(feature = "log")]
8use log::{debug, error, warn};
9
10impl Config {
11    pub fn new() -> Self {
12        let path_base = home_config_path();
13
14        let path_file = path_base.join(Path::new("fluere.toml"));
15
16        #[cfg(feature = "log")]
17        debug!("Using config file from: {:?}", path_file);
18        #[cfg(not(feature = "log"))]
19        println!("Using config file from: {:?}", path_file);
20        if !path_base.exists() {
21            match fs::create_dir_all(&path_base) {
22                Ok(_) => {
23                    #[cfg(feature = "log")]
24                    debug!("Created directory at {:?}", path_base);
25                    ()
26                }
27                Err(e) => {
28                    #[cfg(feature = "log")]
29                    error!("Failed to create directory at {:?}: {}", path_base, e);
30                    #[cfg(not(feature = "log"))]
31                    eprintln!("Failed to create directory at {:?}: {}", path_base, e);
32
33                    return Config::default();
34                }
35            }
36        }
37
38        if !path_file.exists() {
39            Self::save(None, path_file.to_str().unwrap().to_string()).unwrap();
40        }
41
42        match Self::load(path_file.to_str().unwrap().to_string()) {
43            Ok(config) => {
44                #[cfg(feature = "log")]
45                debug!("Loaded configuration from: {:?}", path_file);
46
47                config
48            }
49            Err(_) => {
50                #[cfg(feature = "log")]
51                warn!("failed to load configuration, using default config");
52                #[cfg(not(feature = "log"))]
53                println!("failed to load configuration, using default config");
54                Config::default()
55            }
56        }
57    }
58
59    pub fn load(path: String) -> Result<Self, std::io::Error> {
60        let path = Path::new(&path);
61        let contents = fs::read_to_string(path)?;
62        let config = toml::from_str(&contents).expect("failed to parse config");
63        Ok(config)
64    }
65
66    pub fn save(content: Option<Config>, path: String) -> Result<(), std::io::Error> {
67        let path = Path::new(&path);
68        let contents = match content {
69            Some(config) => toml::to_string(&config).unwrap(),
70            None => toml::to_string(&Config::default()).unwrap(),
71        };
72        fs::write(path, contents)?;
73        Ok(())
74    }
75}
76
77fn home_config_path() -> PathBuf {
78    // Check for the SUDO_USER environment variable
79    let sudo_user = env::var("SUDO_USER");
80
81    let path_base = match sudo_user {
82        Ok(user) => {
83            // on macOS just return the config_dir()
84            if env::consts::OS == "macos" {
85                config_dir().expect("Could not determine the home directory")
86            } else {
87                // If SUDO_USER is set, construct the path using the user's home directory
88                let user_home = format!("/home/{}", user);
89                Path::new(&user_home).join(".config")
90            }
91        }
92        Err(_) => {
93            // If not running under sudo, just use the config_dir function as before
94            config_dir().expect("Could not determine the home directory")
95        }
96    };
97    let path_config = path_base.join("fluere");
98    path_config
99}