mod dotenv;
use std::collections::HashMap;
use std::env;
use std::str::FromStr;
use log::{debug, warn};
fn get_from_envvar<T>(var_name: &str) -> Option<T>
where
T: FromStr,
{
match env::var(var_name) {
Ok(env_value) => match T::from_str(&env_value) {
Ok(value) => Some(value),
Err(_) => {
warn!(
"Casting from environment variable `{}` is failed!",
var_name
);
None
}
},
Err(_) => {
let var_name_upper = var_name.to_uppercase();
debug!(
"environment variable `{}` is not set! Trying `{}`",
var_name, &var_name_upper
);
match env::var(&var_name_upper) {
Ok(env_value) => match T::from_str(&env_value) {
Ok(value) => Some(value),
Err(_) => {
warn!(
"Casting from environment variable `{}` is failed!",
&var_name_upper
);
None
}
},
Err(_) => {
debug!("environment variable `{}` is not set!", &var_name_upper);
None
}
}
}
}
}
fn get_from_dotenv<T>(var_name: &str, dotenv_values: &Option<HashMap<String, String>>) -> Option<T>
where
T: FromStr,
{
match dotenv_values {
Some(dotenv) => match dotenv.get(var_name) {
Some(value) => match T::from_str(value) {
Ok(value) => Some(value),
Err(_) => {
warn!("Casting from dotenv file value `{}` is failed!", var_name);
None
}
},
None => {
let var_name_upper = var_name.to_uppercase();
debug!(
"Dotenv file variable `{}` is not set! Trying {}",
var_name, &var_name_upper
);
match dotenv.get(var_name_upper.as_str()) {
Some(value) => match T::from_str(value) {
Ok(value) => Some(value),
Err(_) => {
warn!(
"Casting from dotenv file value `{}` is failed!",
var_name_upper
);
None
}
},
None => {
debug!("Dotenv file variable `{}` is not set!", &var_name_upper);
None
}
}
}
},
None => None,
}
}
pub fn get_from_env<T>(
field_name: &str,
default_value: Option<T>,
dotenv_values: &Option<HashMap<String, String>>,
) -> T
where
T: FromStr + Default,
{
if let Some(envvar_value) = get_from_envvar::<T>(field_name) {
return envvar_value;
}
if let Some(dotenv_value) = get_from_dotenv::<T>(field_name, dotenv_values) {
return dotenv_value;
}
let mut final_value = T::default();
if let Some(actual_value) = default_value {
final_value = actual_value;
}
final_value
}
extern crate envcast_derive;
pub use dotenv::get_dotenv_file_values;
pub use envcast_derive::FromEnv;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_get_from_envvar_case_success() {
env::set_var("some_var", "value");
assert_eq!(get_from_envvar("some_var"), Some("value".to_string()));
env::remove_var("some_var");
}
#[test]
fn test_get_from_envvar_case_fail_cast() {
env::set_var("some_var", "value");
assert_eq!(get_from_envvar::<i32>("some_var"), None);
env::remove_var("some_var");
}
#[test]
fn test_get_from_envvar_case_fail_and_retry_upper() {
env::set_var("SOME_VAR", "value");
assert_eq!(get_from_envvar("some_var"), Some("value".to_string()));
env::remove_var("SOME_VAR");
}
#[test]
fn test_get_from_envvar_case_retry_upper_and_fail_cast() {
env::set_var("SOME_VAR", "value");
assert_eq!(get_from_envvar::<i32>("some_var"), None);
env::remove_var("SOME_VAR");
}
}