From 265d89d1e8cfd318919e793bbfeceb5b3556cbcb Mon Sep 17 00:00:00 2001 From: Jose Celano Date: Wed, 8 May 2024 13:54:07 +0100 Subject: [PATCH] refactor: replace Config by Figment in Configuration implementation This replaces the crate `config` with `figment` in the Configuration implementation. --- packages/configuration/src/lib.rs | 13 +++++++------ packages/configuration/src/v1/mod.rs | 28 ++++++++-------------------- 2 files changed, 15 insertions(+), 26 deletions(-) diff --git a/packages/configuration/src/lib.rs b/packages/configuration/src/lib.rs index 66650018..78b62442 100644 --- a/packages/configuration/src/lib.rs +++ b/packages/configuration/src/lib.rs @@ -10,10 +10,9 @@ use std::collections::HashMap; use std::sync::Arc; use std::{env, fs}; -use config::ConfigError; use derive_more::Constructor; use thiserror::Error; -use torrust_tracker_located_error::{DynError, Located, LocatedError}; +use torrust_tracker_located_error::{DynError, LocatedError}; /// The maximum number of returned peers for a torrent. pub const TORRENT_PEERS_LIMIT: usize = 74; @@ -142,17 +141,19 @@ pub enum Error { /// Unable to load the configuration from the configuration file. #[error("Failed processing the configuration: {source}")] - ConfigError { source: LocatedError<'static, ConfigError> }, + ConfigError { + source: LocatedError<'static, dyn std::error::Error + Send + Sync>, + }, #[error("The error for errors that can never happen.")] Infallible, } -impl From for Error { +impl From for Error { #[track_caller] - fn from(err: ConfigError) -> Self { + fn from(err: figment::Error) -> Self { Self::ConfigError { - source: Located(err).into(), + source: (Arc::new(err) as DynError).into(), } } } diff --git a/packages/configuration/src/v1/mod.rs b/packages/configuration/src/v1/mod.rs index 486d2c30..6c044c46 100644 --- a/packages/configuration/src/v1/mod.rs +++ b/packages/configuration/src/v1/mod.rs @@ -239,7 +239,8 @@ use std::fs; use std::net::IpAddr; use std::str::FromStr; -use config::{Config, File, FileFormat}; +use figment::providers::{Format, Toml}; +use figment::Figment; use serde::{Deserialize, Serialize}; use torrust_tracker_primitives::{DatabaseDriver, TrackerMode}; @@ -398,18 +399,11 @@ impl Configuration { /// /// Will return `Err` if `path` does not exist or has a bad configuration. pub fn load_from_file(path: &str) -> Result { - // todo: use Figment + let figment = Figment::new().merge(Toml::file(path)); - let config_builder = Config::builder(); + let config: Configuration = figment.extract()?; - #[allow(unused_assignments)] - let mut config = Config::default(); - - config = config_builder.add_source(File::with_name(path)).build()?; - - let torrust_config: Configuration = config.try_deserialize()?; - - Ok(torrust_config) + Ok(config) } /// Saves the default configuration at the given path. @@ -419,8 +413,6 @@ impl Configuration { /// Will return `Err` if `path` is not a valid path or the configuration /// file cannot be created. pub fn create_default_configuration_file(path: &str) -> Result { - // todo: use Figment - let config = Configuration::default(); config.save_to_file(path)?; Ok(config) @@ -435,12 +427,9 @@ impl Configuration { /// /// Will return `Err` if the environment variable does not exist or has a bad configuration. pub fn load(info: &Info) -> Result { - // todo: use Figment + let figment = Figment::new().merge(Toml::string(&info.tracker_toml)); - let config_builder = Config::builder() - .add_source(File::from_str(&info.tracker_toml, FileFormat::Toml)) - .build()?; - let mut config: Configuration = config_builder.try_deserialize()?; + let mut config: Configuration = figment.extract()?; if let Some(ref token) = info.api_admin_token { config.override_api_admin_token(token); @@ -461,14 +450,13 @@ impl Configuration { /// /// Will panic if the configuration cannot be written into the file. pub fn save_to_file(&self, path: &str) -> Result<(), Error> { - // todo: use Figment - fs::write(path, self.to_toml()).expect("Could not write to file!"); Ok(()) } /// Encodes the configuration to TOML. fn to_toml(&self) -> String { + // code-review: do we need to use Figment also to serialize into toml? toml::to_string(self).expect("Could not encode TOML value") } }