From 5993375bff9baec2e89a44bbc21c101240853a27 Mon Sep 17 00:00:00 2001 From: Dmitriy Pleshevskiy Date: Tue, 7 Jan 2020 15:23:50 +0300 Subject: [PATCH] refac: change env_or macro --- itconfig/src/lib.rs | 57 ++++++++++++++++++++++++---- itconfig_tests/tests/config_macro.rs | 22 +++++++++++ 2 files changed, 72 insertions(+), 7 deletions(-) diff --git a/itconfig/src/lib.rs b/itconfig/src/lib.rs index ba297dd..8468de4 100644 --- a/itconfig/src/lib.rs +++ b/itconfig/src/lib.rs @@ -412,7 +412,7 @@ macro_rules! __itconfig_parse_variables { unparsed_meta = $unparsed_meta:tt, meta = $meta:tt, unparsed_concat = [ - $concat_param:tt, + $concat_param:tt$( => $default:expr)?, $($rest:tt)* ], concat = [$($concat:expr,)*], @@ -425,7 +425,7 @@ macro_rules! __itconfig_parse_variables { unparsed_meta = $unparsed_meta, meta = $meta, unparsed_concat = [$($rest)*], - concat = [$($concat,)* __itconfig_concat_param!($concat_param),], + concat = [$($concat,)* __itconfig_concat_param!($concat_param$( => $default)?),], $($current_variable)* }, $($args)* @@ -565,9 +565,20 @@ macro_rules! __itconfig_impl { #[macro_export] #[doc(hidden)] macro_rules! __itconfig_concat_param { - ($env:ident) => ( env_or!(stringify!($env).to_uppercase()) ); + ($env_name:ident => $default:expr) => { + __itconfig_env_or!(stringify!($env_name).to_uppercase(), $default, default) + }; + + ($env_name:ident) => { + env_or!(stringify!($env_name).to_uppercase()) + }; ($str:expr) => ( $str.to_string() ); + + // Invalid syntax + ($($tokens:tt)*) => { + __itconfig_invalid_syntax!(); + }; } @@ -607,7 +618,7 @@ macro_rules! __itconfig_variable { pub fn $name() -> $ty { let value_parts: Vec = vec!($($concat),+); let value = value_parts.join(""); - env_or!(@default $env_name, value) + __itconfig_env_or!(@setenv $env_name, value) } }; @@ -650,23 +661,50 @@ macro_rules! __itconfig_variable { /// ``` #[macro_export(local_inner_macro)] macro_rules! env_or { + // Env without default value ($env_name:expr) => { - env_or!($env_name, format!(r#"Cannot read "{}" environment variable"#, $env_name), panic); + __itconfig_env_or!($env_name, format!(r#"Cannot read "{}" environment variable"#, $env_name), panic); }; + // Env with default value ($env_name:expr, $default:expr) => { - env_or!($env_name, $default, default); + __itconfig_env_or!($env_name, $default, setenv); }; + // Invalid syntax + ($($tokens:tt)*) => { + __itconfig_env_or_invalid_syntax!(); + }; +} + + +#[macro_export] +#[doc(hidden)] +macro_rules! __itconfig_env_or_invalid_syntax { + () => { + compile_error!( + "Invalid `env_or!` syntax. Please see the `env_or!` macro docs for more info.\ + `https://docs.rs/itconfig/latest/itconfig/macro.env_or.html`" + ); + }; +} + + +#[macro_export] +macro_rules! __itconfig_env_or { ($env_name:expr, $default:expr, $token:tt) => {{ use std::env; use itconfig::EnvValue; env::var($env_name) .map(|val| EnvValue::from(val).into()) - .unwrap_or_else(|_| env_or!(@$token $env_name, $default)) + .unwrap_or_else(|_| __itconfig_env_or!(@$token $env_name, $default)) }}; (@default $env_name:expr, $default:expr) => {{ + $default + }}; + + (@setenv $env_name:expr, $default:expr) => {{ env::set_var($env_name, $default.to_string()); $default }}; @@ -674,5 +712,10 @@ macro_rules! env_or { (@panic $env_name:expr, $default:expr) => { panic!($default); }; + + // Invalid syntax + ($($tokens:tt)*) => { + __itconfig_env_or_invalid_syntax!(); + }; } diff --git a/itconfig_tests/tests/config_macro.rs b/itconfig_tests/tests/config_macro.rs index 2ea2b4e..df76514 100644 --- a/itconfig_tests/tests/config_macro.rs +++ b/itconfig_tests/tests/config_macro.rs @@ -315,3 +315,25 @@ fn concatenate_not_defined_environment_variables() { cfg::init(); } + +#[test] +fn default_value_for_concatenate_env_parameter() { + config! { + CONCATENATED_DATABASE_URL < ( + "postgres://", + NOT_DEFINED_PG_USERNAME => "user".to_string(), + ":", + NOT_DEFINED_PG_PASSWORD => "pass".to_string(), + "@", + NOT_DEFINED_PG_HOST => "localhost:5432".to_string(), + "/", + NOT_DEFINED_PG_DB => "test".to_string(), + ), + } + + cfg::init(); + assert_eq!( + env::var("CONCATENATED_DATABASE_URL"), + Ok("postgres://user:pass@localhost:5432/test".to_string()) + ); +}