Krys4lide/crates/utils/src/config.rs

69 lines
2.2 KiB
Rust

use std::{env, path::PathBuf, sync::atomic::AtomicBool};
use directories::ProjectDirs;
use dotenv::from_path;
use thiserror::Error;
const CONFIG_FILE_NAME: &str = ".env";
static CONFIG_INITIALIZED: AtomicBool = AtomicBool::new(false);
#[derive(Debug, Error)]
pub enum ConfigError {
#[error("No config file {0} found in the following directories: {1:#?}")]
ConfigFileNotFound(String, Vec<PathBuf>),
#[error("Failed to load config file: {0}")]
LoadConfigError(#[from] dotenv::Error),
#[error("Environment variable error: {0}")]
EnvVarError(#[from] std::env::VarError),
}
pub fn get_config_dirs() -> Vec<PathBuf> {
let mut config_dirs = vec![
PathBuf::from(""), // Current directory
];
if let Ok(manifest_dir) = env::var("CARGO_MANIFEST_DIR") {
config_dirs.push(PathBuf::from(manifest_dir));
}
if let Some(proj_dirs) = ProjectDirs::from("org", "P4pillon", "Krys4lide") {
config_dirs.push(proj_dirs.config_dir().to_path_buf());
}
config_dirs
}
pub fn get_config_files() -> Result<Vec<PathBuf>, ConfigError> {
let config_dirs = get_config_dirs();
let mut config_files = Vec::new();
for config_dir in config_dirs.iter() {
let config_file = config_dir.join(CONFIG_FILE_NAME);
if config_file.exists() {
config_files.push(config_file);
}
}
if config_files.is_empty() {
return Err(ConfigError::ConfigFileNotFound(
CONFIG_FILE_NAME.to_string(),
config_dirs,
));
}
Ok(config_files)
}
pub fn load_config(force: Option<bool>) -> Result<(), ConfigError> {
let force = force.unwrap_or(false);
if CONFIG_INITIALIZED.load(std::sync::atomic::Ordering::Relaxed) && force {
println!("DEBUG: Config already initialized, skipping");
return Ok(());
}
let config_files = get_config_files()?;
// Load the first config file found
// TODO: add a verbose log to list all config files found
println!(
"DEBUG: Config files found (1st loaded): {:#?}",
config_files
);
from_path(config_files[0].as_path()).map_err(ConfigError::LoadConfigError)?;
CONFIG_INITIALIZED.store(true, std::sync::atomic::Ordering::Relaxed);
Ok(())
}