From f30d943add8ce782349447b7f72ca2302802f7fc Mon Sep 17 00:00:00 2001
From: librelois <elois@ifee.fr>
Date: Mon, 27 Jan 2020 00:56:48 +0100
Subject: [PATCH] [feat] core: load module conf from env var as a priority

#141
---
 Cargo.lock                 |  2 ++
 lib/core/core/Cargo.toml   |  1 +
 lib/core/core/src/lib.rs   | 34 +++++++++++++++++++++++++++++-----
 lib/core/module/Cargo.toml |  1 +
 lib/core/module/src/lib.rs |  3 +++
 5 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index e020f1ce..b202936a 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1028,6 +1028,7 @@ dependencies = [
  "durs-module 0.3.0-dev",
  "durs-network 0.3.0-dev",
  "durs-network-documents 0.4.0",
+ "envy 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "fern 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1111,6 +1112,7 @@ dependencies = [
  "dup-crypto 0.7.0",
  "durs-common-tools 0.2.0",
  "durs-network-documents 0.4.0",
+ "envy 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
diff --git a/lib/core/core/Cargo.toml b/lib/core/core/Cargo.toml
index 5e8b4e7c..8e85b938 100644
--- a/lib/core/core/Cargo.toml
+++ b/lib/core/core/Cargo.toml
@@ -24,6 +24,7 @@ durs-message =  { path = "../message" }
 durs-module = { path = "../module" }
 durs-network = { path = "../network" }
 durs-network-documents = { path = "../../dunp/network-documents" }
+envy = "0.4.1"
 failure = "0.1.5"
 fern = { version = "0.5.8", features = ["colored"] }
 log = "0.4.*"
diff --git a/lib/core/core/src/lib.rs b/lib/core/core/src/lib.rs
index edb2da35..cecf3fb6 100644
--- a/lib/core/core/src/lib.rs
+++ b/lib/core/core/src/lib.rs
@@ -44,6 +44,7 @@ use crate::errors::DursCoreError;
 use dubp_currency_params::CurrencyName;
 use durs_bc::{dbex::DbExQuery, BlockchainModule};
 use durs_common_tools::fatal_error;
+use durs_common_tools::traits::merge::Merge;
 pub use durs_conf::{
     constants::KEYPAIRS_FILENAME, keypairs::cli::*, ChangeGlobalConf, DuRsConf, DuniterKeyPairs,
 };
@@ -574,19 +575,42 @@ pub fn get_module_conf_and_keys<M: DursModule<DuRsConf, DursMsg>>(
     ))
 }
 
+fn get_env_module_user_conf<ModuleUserConf: serde::de::DeserializeOwned>(
+    module_name: ModuleStaticName,
+) -> Result<ModuleUserConf, ModuleConfError> {
+    let prefix = format!(
+        "{}{}",
+        durs_conf::constants::DURS_ENV_PREFIX,
+        module_name.0.to_ascii_uppercase()
+    );
+
+    envy::prefixed(prefix)
+        .from_env::<ModuleUserConf>()
+        .map_err(ModuleConfError::EnvyErr)
+}
+
 /// get module conf
 pub fn get_module_conf<M: DursModule<DuRsConf, DursMsg>>(
     currency_name: Option<&CurrencyName>,
     global_conf: &<DuRsConf as DursConfTrait>::GlobalConf,
     module_conf_json: Option<serde_json::Value>,
 ) -> Result<(M::ModuleConf, Option<M::ModuleUserConf>), ModuleConfError> {
-    if let Some(module_conf_json) = module_conf_json {
-        let module_user_conf: Option<M::ModuleUserConf> =
+    let file_module_user_conf: M::ModuleUserConf = if let Some(module_conf_json) = module_conf_json
+    {
+        let file_module_user_conf_opt: Option<M::ModuleUserConf> =
             serde_json::from_str(module_conf_json.to_string().as_str())?;
-        M::generate_module_conf(currency_name, global_conf, module_user_conf)
+        file_module_user_conf_opt.unwrap_or_default()
     } else {
-        M::generate_module_conf(currency_name, global_conf, None)
-    }
+        M::ModuleUserConf::default()
+    };
+
+    let env_module_user_conf = get_env_module_user_conf::<M::ModuleUserConf>(M::name())?;
+
+    M::generate_module_conf(
+        currency_name,
+        global_conf,
+        Some(file_module_user_conf.merge(env_module_user_conf)),
+    )
 }
 
 /// Launch databases explorer
diff --git a/lib/core/module/Cargo.toml b/lib/core/module/Cargo.toml
index d7aa7cdb..f19db073 100644
--- a/lib/core/module/Cargo.toml
+++ b/lib/core/module/Cargo.toml
@@ -15,6 +15,7 @@ dubp-currency-params = { path = "../../dubp/currency-params" }
 dubp-user-docs = { path = "../../dubp/user-docs" }
 durs-common-tools = { path = "../../tools/common-tools" }
 durs-network-documents = { path = "../../dunp/network-documents" }
+envy = "0.4.1"
 failure = "0.1.5"
 log = "0.4.*"
 serde = "1.0.*"
diff --git a/lib/core/module/src/lib.rs b/lib/core/module/src/lib.rs
index 23360f7c..df8a38fe 100644
--- a/lib/core/module/src/lib.rs
+++ b/lib/core/module/src/lib.rs
@@ -362,6 +362,9 @@ pub enum ModuleConfError {
         /// Cause
         cause: String,
     },
+    /// Error when get conf from environment variables
+    #[fail(display = "Error when get conf from environment variables: {}", _0)]
+    EnvyErr(envy::Error),
     /// Invalid field
     #[fail(display = "Field '{}' is invalid: {}", field_name, cause)]
     InvalidField {
-- 
GitLab