feat: migrate utils::config from anyhow to thiserror and handle a "single config init" mechanism

This commit is contained in:
Florian Briand 2024-09-16 22:49:28 +02:00
parent 345190dfeb
commit 502dc6f77d
Signed by: florian_briand
GPG Key ID: CC981B9E6B98E70B
4 changed files with 33 additions and 11 deletions

1
Cargo.lock generated
View File

@ -5046,6 +5046,7 @@ dependencies = [
"anyhow", "anyhow",
"directories", "directories",
"dotenv", "dotenv",
"thiserror",
] ]
[[package]] [[package]]

View File

@ -9,7 +9,7 @@ use thiserror::Error;
use crate::cps::lire_carte; use crate::cps::lire_carte;
use crate::libssv::{SSV_InitLIB2, SSV_LireConfig}; use crate::libssv::{SSV_InitLIB2, SSV_LireConfig};
use ::utils::config::load_config; use ::utils::config::{load_config, ConfigError};
#[derive(Error, Debug)] #[derive(Error, Debug)]
pub enum SSVDemoError { pub enum SSVDemoError {
@ -18,7 +18,7 @@ pub enum SSVDemoError {
#[error(transparent)] #[error(transparent)]
SSVLibErrorCode(#[from] crate::libssv::LibSSVError), SSVLibErrorCode(#[from] crate::libssv::LibSSVError),
#[error(transparent)] #[error(transparent)]
Anyhow(#[from] anyhow::Error), Configuration(#[from] ConfigError),
} }
fn ssv_init_lib_2() -> Result<(), SSVDemoError> { fn ssv_init_lib_2() -> Result<(), SSVDemoError> {
@ -71,7 +71,7 @@ pub fn demo() -> Result<(), SSVDemoError> {
println!("------- Demo for the SSV library --------"); println!("------- Demo for the SSV library --------");
load_config()?; load_config(None)?;
ssv_init_lib_2()?; ssv_init_lib_2()?;

View File

@ -7,3 +7,4 @@ edition = "2021"
anyhow = "1.0" anyhow = "1.0"
directories = "5.0" directories = "5.0"
dotenv = "0.15" dotenv = "0.15"
thiserror = "1.0"

View File

@ -1,11 +1,23 @@
use std::{env, path::PathBuf}; use std::{env, path::PathBuf, sync::atomic::AtomicBool};
use anyhow::{bail, Context, Result};
use directories::ProjectDirs; use directories::ProjectDirs;
use dotenv::from_path; use dotenv::from_path;
use thiserror::Error;
const CONFIG_FILE_NAME: &str = ".env"; 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> { pub fn get_config_dirs() -> Vec<PathBuf> {
let mut config_dirs = vec![ let mut config_dirs = vec![
PathBuf::from(""), // Current directory PathBuf::from(""), // Current directory
@ -19,7 +31,7 @@ pub fn get_config_dirs() -> Vec<PathBuf> {
config_dirs config_dirs
} }
pub fn get_config_files() -> Result<Vec<PathBuf>> { pub fn get_config_files() -> Result<Vec<PathBuf>, ConfigError> {
let config_dirs = get_config_dirs(); let config_dirs = get_config_dirs();
let mut config_files = Vec::new(); let mut config_files = Vec::new();
for config_dir in config_dirs.iter() { for config_dir in config_dirs.iter() {
@ -29,14 +41,20 @@ pub fn get_config_files() -> Result<Vec<PathBuf>> {
} }
} }
if config_files.is_empty() { if config_files.is_empty() {
bail!( return Err(ConfigError::ConfigFileNotFound(
"No config file {CONFIG_FILE_NAME} found in the following directories: {config_dirs:#?}" CONFIG_FILE_NAME.to_string(),
); config_dirs,
));
} }
Ok(config_files) Ok(config_files)
} }
pub fn load_config() -> Result<()> { 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()?; let config_files = get_config_files()?;
// Load the first config file found // Load the first config file found
// TODO: add a verbose log to list all config files found // TODO: add a verbose log to list all config files found
@ -44,5 +62,7 @@ pub fn load_config() -> Result<()> {
"DEBUG: Config files found (1st loaded): {:#?}", "DEBUG: Config files found (1st loaded): {:#?}",
config_files config_files
); );
from_path(config_files[0].as_path()).context("Failed to load config file") from_path(config_files[0].as_path()).map_err(ConfigError::LoadConfigError)?;
CONFIG_INITIALIZED.store(true, std::sync::atomic::Ordering::Relaxed);
Ok(())
} }