Merge pull request #7 from icetemple/concat-var
feat: concatenated variables
This commit is contained in:
commit
17e9ccfec8
5 changed files with 402 additions and 31 deletions
18
README.md
18
README.md
|
@ -20,6 +20,17 @@ config! {
|
||||||
DEBUG: bool => true,
|
DEBUG: bool => true,
|
||||||
HOST: String => "127.0.0.1".to_string(),
|
HOST: String => "127.0.0.1".to_string(),
|
||||||
|
|
||||||
|
DATABASE_URL < (
|
||||||
|
"postgres://",
|
||||||
|
POSTGRES_USERNAME => "user",
|
||||||
|
":",
|
||||||
|
POSTGRES_PASSWORD => "pass",
|
||||||
|
"@",
|
||||||
|
POSTGRES_HOST => "localhost:5432",
|
||||||
|
"/",
|
||||||
|
POSTGRES_DB => "test",
|
||||||
|
),
|
||||||
|
|
||||||
NAMESPACE {
|
NAMESPACE {
|
||||||
#[env_name = "MY_CUSTOM_NAME"]
|
#[env_name = "MY_CUSTOM_NAME"]
|
||||||
FOO: bool,
|
FOO: bool,
|
||||||
|
@ -37,8 +48,9 @@ fn main () {
|
||||||
env::set_var("MY_CUSTOM_NAME", "t");
|
env::set_var("MY_CUSTOM_NAME", "t");
|
||||||
|
|
||||||
cfg::init();
|
cfg::init();
|
||||||
assert_eq(cfg::HOST(), String::from("127.0.0.1"));
|
assert_eq!(cfg::HOST(), String::from("127.0.0.1"));
|
||||||
assert_eq(cfg::NAMESPACE::FOO(), true);
|
assert_eq!(cfg::DATABASE_URL(), String::from("postgres://user:pass@localhost:5432/test"));
|
||||||
|
assert_eq!(cfg::NAMESPACE::FOO(), true);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -55,7 +67,7 @@ cargo test
|
||||||
* [x] Custom env name
|
* [x] Custom env name
|
||||||
* [x] Support feature config and other meta directives
|
* [x] Support feature config and other meta directives
|
||||||
* [x] Add default value to env if env is not found
|
* [x] Add default value to env if env is not found
|
||||||
* [ ] Concat env variables to one variable
|
* [x] Concat env variables to one variable
|
||||||
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "itconfig"
|
name = "itconfig"
|
||||||
version = "0.6.0"
|
version = "0.7.0"
|
||||||
authors = ["Dmitriy Pleshevskiy <dmitriy@ideascup.me>"]
|
authors = ["Dmitriy Pleshevskiy <dmitriy@ideascup.me>"]
|
||||||
description = "Easy build a configs from environment variables and use it in globally."
|
description = "Easy build a configs from environment variables and use it in globally."
|
||||||
categories = ["config", "web-programming"]
|
categories = ["config", "web-programming"]
|
||||||
|
|
|
@ -16,6 +16,17 @@ config! {
|
||||||
DEBUG: bool => true,
|
DEBUG: bool => true,
|
||||||
HOST: String => "127.0.0.1".to_string(),
|
HOST: String => "127.0.0.1".to_string(),
|
||||||
|
|
||||||
|
DATABASE_URL < (
|
||||||
|
"postgres://",
|
||||||
|
POSTGRES_USERNAME => "user",
|
||||||
|
":",
|
||||||
|
POSTGRES_PASSWORD => "pass",
|
||||||
|
"@",
|
||||||
|
POSTGRES_HOST => "localhost:5432",
|
||||||
|
"/",
|
||||||
|
POSTGRES_DB => "test",
|
||||||
|
),
|
||||||
|
|
||||||
NAMESPACE {
|
NAMESPACE {
|
||||||
#[env_name = "MY_CUSTOM_NAME"]
|
#[env_name = "MY_CUSTOM_NAME"]
|
||||||
FOO: bool,
|
FOO: bool,
|
||||||
|
@ -33,8 +44,9 @@ fn main () {
|
||||||
env::set_var("MY_CUSTOM_NAME", "t");
|
env::set_var("MY_CUSTOM_NAME", "t");
|
||||||
|
|
||||||
cfg::init();
|
cfg::init();
|
||||||
assert_eq(cfg::HOST(), String::from("127.0.0.1"));
|
assert_eq!(cfg::HOST(), String::from("127.0.0.1"));
|
||||||
assert_eq(cfg::NAMESPACE::FOO(), true);
|
assert_eq!(cfg::DATABASE_URL(), String::from("postgres://user:pass@localhost:5432/test"));
|
||||||
|
assert_eq!(cfg::NAMESPACE::FOO(), true);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -45,7 +57,7 @@ fn main () {
|
||||||
* [x] Custom env name
|
* [x] Custom env name
|
||||||
* [x] Support feature config and other meta directives
|
* [x] Support feature config and other meta directives
|
||||||
* [x] Add default value to env if env is not found
|
* [x] Add default value to env if env is not found
|
||||||
* [ ] Concat env variables to one variable
|
* [x] Concat env variables to one variable
|
||||||
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
|
@ -12,7 +12,18 @@
|
||||||
//!
|
//!
|
||||||
//! config! {
|
//! config! {
|
||||||
//! DEBUG: bool => true,
|
//! DEBUG: bool => true,
|
||||||
//! HOST: String => "127.0.0.1".to_string(),
|
//! HOST: String => "127.0.0.1",
|
||||||
|
//!
|
||||||
|
//! DATABASE_URL < (
|
||||||
|
//! "postgres://",
|
||||||
|
//! POSTGRES_USERNAME => "user",
|
||||||
|
//! ":",
|
||||||
|
//! POSTGRES_PASSWORD => "pass",
|
||||||
|
//! "@",
|
||||||
|
//! POSTGRES_HOST => "localhost:5432",
|
||||||
|
//! "/",
|
||||||
|
//! POSTGRES_DB => "test",
|
||||||
|
//! ),
|
||||||
//!
|
//!
|
||||||
//! NAMESPACE {
|
//! NAMESPACE {
|
||||||
//! #[env_name = "MY_CUSTOM_NAME"]
|
//! #[env_name = "MY_CUSTOM_NAME"]
|
||||||
|
@ -28,6 +39,7 @@
|
||||||
//!
|
//!
|
||||||
//! cfg::init();
|
//! cfg::init();
|
||||||
//! assert_eq!(cfg::HOST(), String::from("127.0.0.1"));
|
//! assert_eq!(cfg::HOST(), String::from("127.0.0.1"));
|
||||||
|
//! assert_eq!(cfg::DATABASE_URL(), String::from("postgres://user:pass@localhost:5432/test"));
|
||||||
//! assert_eq!(cfg::NAMESPACE::FOO(), true);
|
//! assert_eq!(cfg::NAMESPACE::FOO(), true);
|
||||||
//! }
|
//! }
|
||||||
//! ```
|
//! ```
|
||||||
|
@ -83,6 +95,8 @@ impl From<EnvValue> for String {
|
||||||
/// All variables are required and program will panic if some variables haven't value, but you
|
/// All variables are required and program will panic if some variables haven't value, but you
|
||||||
/// can add default value for specific variable.
|
/// can add default value for specific variable.
|
||||||
///
|
///
|
||||||
|
/// Starts with v0.6.0 if you don't have an optional variable, the variable is set automatically.
|
||||||
|
///
|
||||||
/// Example usage
|
/// Example usage
|
||||||
/// -------------
|
/// -------------
|
||||||
///
|
///
|
||||||
|
@ -104,7 +118,7 @@ impl From<EnvValue> for String {
|
||||||
/// # env::set_var("DATABASE_URL", "postgres://u:p@localhost:5432/db");
|
/// # env::set_var("DATABASE_URL", "postgres://u:p@localhost:5432/db");
|
||||||
/// config! {
|
/// config! {
|
||||||
/// DATABASE_URL: String,
|
/// DATABASE_URL: String,
|
||||||
/// HOST: String => "127.0.0.1".to_string(),
|
/// HOST: String => "127.0.0.1",
|
||||||
/// }
|
/// }
|
||||||
/// # cfg::init()
|
/// # cfg::init()
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -127,6 +141,9 @@ impl From<EnvValue> for String {
|
||||||
/// assert_eq!(configuration::DEBUG(), true);
|
/// assert_eq!(configuration::DEBUG(), true);
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
|
/// Namespaces
|
||||||
|
/// ----------
|
||||||
|
///
|
||||||
/// You can use namespaces for env variables
|
/// You can use namespaces for env variables
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
|
@ -148,6 +165,9 @@ impl From<EnvValue> for String {
|
||||||
/// # cfg::init()
|
/// # cfg::init()
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
|
/// Meta
|
||||||
|
/// ----
|
||||||
|
///
|
||||||
/// If you want to read custom env name for variable you can change it manually.
|
/// If you want to read custom env name for variable you can change it manually.
|
||||||
///
|
///
|
||||||
/// **A variable in the nameespace will lose environment prefix**
|
/// **A variable in the nameespace will lose environment prefix**
|
||||||
|
@ -186,6 +206,57 @@ impl From<EnvValue> for String {
|
||||||
/// # fn main() {}
|
/// # fn main() {}
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
|
/// Concatenate
|
||||||
|
/// -----------
|
||||||
|
///
|
||||||
|
/// Try to concatenate env variable or strings or both to you env variable. It's easy!
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// # #[macro_use] extern crate itconfig;
|
||||||
|
/// # use std::env;
|
||||||
|
/// env::set_var("POSTGRES_USERNAME", "user");
|
||||||
|
/// env::set_var("POSTGRES_PASSWORD", "pass");
|
||||||
|
///
|
||||||
|
/// config! {
|
||||||
|
/// DATABASE_URL < (
|
||||||
|
/// "postgres://",
|
||||||
|
/// POSTGRES_USERNAME,
|
||||||
|
/// ":",
|
||||||
|
/// POSTGRES_PASSWORD,
|
||||||
|
/// "@",
|
||||||
|
/// POSTGRES_HOST => "localhost:5432",
|
||||||
|
/// "/",
|
||||||
|
/// POSTGRES_DB => "test",
|
||||||
|
/// ),
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// cfg::init();
|
||||||
|
/// assert_eq!(cfg::DATABASE_URL(), "postgres://user:pass@localhost:5432/test".to_string())
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Concatinated variables can be only strings and support all features like namespaces and meta.
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// # #[macro_use] extern crate itconfig;
|
||||||
|
/// config! {
|
||||||
|
/// CONCATED_NAMESPACE {
|
||||||
|
/// #[env_name = "DATABASE_URL"]
|
||||||
|
/// CONCAT_ENVVAR < (
|
||||||
|
/// "postgres://",
|
||||||
|
/// NOT_DEFINED_PG_USERNAME => "user",
|
||||||
|
/// ":",
|
||||||
|
/// NOT_DEFINED_PG_PASSWORD => "pass",
|
||||||
|
/// "@",
|
||||||
|
/// NOT_DEFINED_PG_HOST => "localhost:5432",
|
||||||
|
/// "/",
|
||||||
|
/// NOT_DEFINED_PG_DB => "test",
|
||||||
|
/// ),
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// cfg::init();
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
/// ---
|
/// ---
|
||||||
///
|
///
|
||||||
/// This module will also contain helper method:
|
/// This module will also contain helper method:
|
||||||
|
@ -211,7 +282,7 @@ impl From<EnvValue> for String {
|
||||||
///
|
///
|
||||||
/// config! {
|
/// config! {
|
||||||
/// DEBUG: bool => true,
|
/// DEBUG: bool => true,
|
||||||
/// HOST: String => "127.0.0.1".to_string(),
|
/// HOST: String => "127.0.0.1",
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// fn main () {
|
/// fn main () {
|
||||||
|
@ -308,6 +379,29 @@ macro_rules! __itconfig_parse_variables {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Find concatenated variable
|
||||||
|
(
|
||||||
|
tokens = [
|
||||||
|
$(#$meta:tt)*
|
||||||
|
$name:ident < ($($inner:tt)+),
|
||||||
|
$($rest:tt)*
|
||||||
|
],
|
||||||
|
$($args:tt)*
|
||||||
|
) => {
|
||||||
|
__itconfig_parse_variables! {
|
||||||
|
current_variable = {
|
||||||
|
unparsed_meta = [$(#$meta)*],
|
||||||
|
meta = [],
|
||||||
|
unparsed_concat = [$($inner)+],
|
||||||
|
concat = [],
|
||||||
|
name = $name,
|
||||||
|
ty = String,
|
||||||
|
},
|
||||||
|
tokens = [$($rest)*],
|
||||||
|
$($args)*
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Find variable
|
// Find variable
|
||||||
(
|
(
|
||||||
tokens = [
|
tokens = [
|
||||||
|
@ -321,6 +415,8 @@ macro_rules! __itconfig_parse_variables {
|
||||||
current_variable = {
|
current_variable = {
|
||||||
unparsed_meta = [$(#$meta)*],
|
unparsed_meta = [$(#$meta)*],
|
||||||
meta = [],
|
meta = [],
|
||||||
|
unparsed_concat = [],
|
||||||
|
concat = [],
|
||||||
name = $name,
|
name = $name,
|
||||||
ty = $ty,
|
ty = $ty,
|
||||||
$(default = $default,)?
|
$(default = $default,)?
|
||||||
|
@ -338,6 +434,8 @@ macro_rules! __itconfig_parse_variables {
|
||||||
$($rest:tt)*
|
$($rest:tt)*
|
||||||
],
|
],
|
||||||
meta = $meta:tt,
|
meta = $meta:tt,
|
||||||
|
unparsed_concat = $unparsed_concat:tt,
|
||||||
|
concat = $concat:tt,
|
||||||
name = $name:ident,
|
name = $name:ident,
|
||||||
$($current_variable:tt)*
|
$($current_variable:tt)*
|
||||||
},
|
},
|
||||||
|
@ -347,6 +445,8 @@ macro_rules! __itconfig_parse_variables {
|
||||||
current_variable = {
|
current_variable = {
|
||||||
unparsed_meta = [$($rest)*],
|
unparsed_meta = [$($rest)*],
|
||||||
meta = $meta,
|
meta = $meta,
|
||||||
|
unparsed_concat = $unparsed_concat,
|
||||||
|
concat = $concat,
|
||||||
name = $name,
|
name = $name,
|
||||||
env_name = $env_name,
|
env_name = $env_name,
|
||||||
$($current_variable)*
|
$($current_variable)*
|
||||||
|
@ -363,7 +463,6 @@ macro_rules! __itconfig_parse_variables {
|
||||||
$($rest:tt)*
|
$($rest:tt)*
|
||||||
],
|
],
|
||||||
meta = [$(#$meta:tt,)*],
|
meta = [$(#$meta:tt,)*],
|
||||||
name = $name:ident,
|
|
||||||
$($current_variable:tt)*
|
$($current_variable:tt)*
|
||||||
},
|
},
|
||||||
$($args:tt)*
|
$($args:tt)*
|
||||||
|
@ -372,7 +471,32 @@ macro_rules! __itconfig_parse_variables {
|
||||||
current_variable = {
|
current_variable = {
|
||||||
unparsed_meta = [$($rest)*],
|
unparsed_meta = [$($rest)*],
|
||||||
meta = [$(#$meta,)* #$stranger_meta,],
|
meta = [$(#$meta,)* #$stranger_meta,],
|
||||||
name = $name,
|
$($current_variable)*
|
||||||
|
},
|
||||||
|
$($args)*
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Parse concat params
|
||||||
|
(
|
||||||
|
current_variable = {
|
||||||
|
unparsed_meta = $unparsed_meta:tt,
|
||||||
|
meta = $meta:tt,
|
||||||
|
unparsed_concat = [
|
||||||
|
$concat_param:tt$( => $default:expr)?,
|
||||||
|
$($rest:tt)*
|
||||||
|
],
|
||||||
|
concat = [$($concat:expr,)*],
|
||||||
|
$($current_variable:tt)*
|
||||||
|
},
|
||||||
|
$($args:tt)*
|
||||||
|
) => {
|
||||||
|
__itconfig_parse_variables! {
|
||||||
|
current_variable = {
|
||||||
|
unparsed_meta = $unparsed_meta,
|
||||||
|
meta = $meta,
|
||||||
|
unparsed_concat = [$($rest)*],
|
||||||
|
concat = [$($concat,)* __itconfig_concat_param!($concat_param$( => $default)?),],
|
||||||
$($current_variable)*
|
$($current_variable)*
|
||||||
},
|
},
|
||||||
$($args)*
|
$($args)*
|
||||||
|
@ -383,6 +507,8 @@ macro_rules! __itconfig_parse_variables {
|
||||||
(
|
(
|
||||||
current_variable = {
|
current_variable = {
|
||||||
unparsed_meta = [],
|
unparsed_meta = [],
|
||||||
|
meta = $meta:tt,
|
||||||
|
unparsed_concat = [],
|
||||||
$($current_variable:tt)*
|
$($current_variable:tt)*
|
||||||
},
|
},
|
||||||
tokens = $tokens:tt,
|
tokens = $tokens:tt,
|
||||||
|
@ -391,7 +517,7 @@ macro_rules! __itconfig_parse_variables {
|
||||||
) => {
|
) => {
|
||||||
__itconfig_parse_variables! {
|
__itconfig_parse_variables! {
|
||||||
tokens = $tokens,
|
tokens = $tokens,
|
||||||
variables = [$($variables,)* { $($current_variable)* },],
|
variables = [$($variables,)* { meta = $meta, $($current_variable)* },],
|
||||||
$($args)*
|
$($args)*
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -445,12 +571,14 @@ macro_rules! __itconfig_impl {
|
||||||
(
|
(
|
||||||
variables = [$({
|
variables = [$({
|
||||||
meta = $var_meta:tt,
|
meta = $var_meta:tt,
|
||||||
|
concat = $var_concat:tt,
|
||||||
name = $var_name:ident,
|
name = $var_name:ident,
|
||||||
$($variable:tt)*
|
$($variable:tt)*
|
||||||
},)*],
|
},)*],
|
||||||
namespaces = [$({
|
namespaces = [$({
|
||||||
variables = [$({
|
variables = [$({
|
||||||
meta = $ns_var_meta:tt,
|
meta = $ns_var_meta:tt,
|
||||||
|
concat = $ns_var_concat:tt,
|
||||||
name = $ns_var_name:ident,
|
name = $ns_var_name:ident,
|
||||||
$($ns_variables:tt)*
|
$($ns_variables:tt)*
|
||||||
},)*],
|
},)*],
|
||||||
|
@ -464,10 +592,17 @@ macro_rules! __itconfig_impl {
|
||||||
) => {
|
) => {
|
||||||
pub mod $mod_name {
|
pub mod $mod_name {
|
||||||
#![allow(non_snake_case)]
|
#![allow(non_snake_case)]
|
||||||
|
use std::env;
|
||||||
|
use itconfig::EnvValue;
|
||||||
|
|
||||||
$(
|
$(
|
||||||
pub mod $ns_name {
|
pub mod $ns_name {
|
||||||
|
use std::env;
|
||||||
|
use itconfig::EnvValue;
|
||||||
|
|
||||||
$(__itconfig_variable! {
|
$(__itconfig_variable! {
|
||||||
meta = $ns_var_meta,
|
meta = $ns_var_meta,
|
||||||
|
concat = $ns_var_concat,
|
||||||
name = $ns_var_name,
|
name = $ns_var_name,
|
||||||
env_prefix = $ns_env_prefix,
|
env_prefix = $ns_env_prefix,
|
||||||
$($ns_variables)*
|
$($ns_variables)*
|
||||||
|
@ -483,6 +618,7 @@ macro_rules! __itconfig_impl {
|
||||||
|
|
||||||
$(__itconfig_variable! {
|
$(__itconfig_variable! {
|
||||||
meta = $var_meta,
|
meta = $var_meta,
|
||||||
|
concat = $var_concat,
|
||||||
name = $var_name,
|
name = $var_name,
|
||||||
env_prefix = $env_prefix,
|
env_prefix = $env_prefix,
|
||||||
$($variable)*
|
$($variable)*
|
||||||
|
@ -497,12 +633,36 @@ macro_rules! __itconfig_impl {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
#[doc(hidden)]
|
||||||
|
macro_rules! __itconfig_concat_param {
|
||||||
|
// Find env parameter with default value
|
||||||
|
($env_name:ident => $default:expr) => {
|
||||||
|
__itconfig_variable_helper!(stringify!($env_name).to_uppercase(), $default, default)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Find env parameter without default value
|
||||||
|
($env_name:ident) => {
|
||||||
|
env_or!(stringify!($env_name).to_uppercase())
|
||||||
|
};
|
||||||
|
|
||||||
|
// Find string parameter
|
||||||
|
($str:expr) => ( $str.to_string() );
|
||||||
|
|
||||||
|
// Invalid syntax
|
||||||
|
($($tokens:tt)*) => {
|
||||||
|
__itconfig_invalid_syntax!();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
macro_rules! __itconfig_variable {
|
macro_rules! __itconfig_variable {
|
||||||
// Set default env name
|
// Set default env name
|
||||||
(
|
(
|
||||||
meta = $meta:tt,
|
meta = $meta:tt,
|
||||||
|
concat = $concat:tt,
|
||||||
name = $name:ident,
|
name = $name:ident,
|
||||||
env_prefix = $env_prefix:expr,
|
env_prefix = $env_prefix:expr,
|
||||||
ty = $ty:ty,
|
ty = $ty:ty,
|
||||||
|
@ -510,6 +670,7 @@ macro_rules! __itconfig_variable {
|
||||||
) => {
|
) => {
|
||||||
__itconfig_variable! {
|
__itconfig_variable! {
|
||||||
meta = $meta,
|
meta = $meta,
|
||||||
|
concat = $concat,
|
||||||
name = $name,
|
name = $name,
|
||||||
env_prefix = $env_prefix,
|
env_prefix = $env_prefix,
|
||||||
env_name = concat!($env_prefix, stringify!($name)).to_uppercase(),
|
env_name = concat!($env_prefix, stringify!($name)).to_uppercase(),
|
||||||
|
@ -518,9 +679,28 @@ macro_rules! __itconfig_variable {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add method
|
// Add method for concatenated variable
|
||||||
(
|
(
|
||||||
meta = [$(#$meta:tt,)*],
|
meta = [$(#$meta:tt,)*],
|
||||||
|
concat = [$($concat:expr,)+],
|
||||||
|
name = $name:ident,
|
||||||
|
env_prefix = $env_prefix:expr,
|
||||||
|
env_name = $env_name:expr,
|
||||||
|
ty = $ty:ty,
|
||||||
|
$($args:tt)*
|
||||||
|
) => {
|
||||||
|
$(#$meta)*
|
||||||
|
pub fn $name() -> $ty {
|
||||||
|
let value_parts: Vec<String> = vec!($($concat),+);
|
||||||
|
let value = value_parts.join("");
|
||||||
|
__itconfig_variable_helper!(@setenv $env_name, value)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Add method for env variable
|
||||||
|
(
|
||||||
|
meta = [$(#$meta:tt,)*],
|
||||||
|
concat = [],
|
||||||
name = $name:ident,
|
name = $name:ident,
|
||||||
env_prefix = $env_prefix:expr,
|
env_prefix = $env_prefix:expr,
|
||||||
env_name = $env_name:expr,
|
env_name = $env_name:expr,
|
||||||
|
@ -556,29 +736,66 @@ macro_rules! __itconfig_variable {
|
||||||
/// ```
|
/// ```
|
||||||
#[macro_export(local_inner_macro)]
|
#[macro_export(local_inner_macro)]
|
||||||
macro_rules! env_or {
|
macro_rules! env_or {
|
||||||
|
// Env without default value
|
||||||
($env_name:expr) => {
|
($env_name:expr) => {
|
||||||
env_or!($env_name, format!(r#"Cannot read "{}" environment variable"#, $env_name), panic);
|
__itconfig_variable_helper!($env_name, format!(r#"Cannot read "{}" environment variable"#, $env_name), panic);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Env with default value
|
||||||
($env_name:expr, $default:expr) => {
|
($env_name:expr, $default:expr) => {
|
||||||
env_or!($env_name, $default, default);
|
__itconfig_variable_helper!($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]
|
||||||
|
#[doc(hidden)]
|
||||||
|
macro_rules! __itconfig_variable_helper {
|
||||||
|
// Get env variable
|
||||||
($env_name:expr, $default:expr, $token:tt) => {{
|
($env_name:expr, $default:expr, $token:tt) => {{
|
||||||
use std::env;
|
use std::env;
|
||||||
use itconfig::EnvValue;
|
use itconfig::EnvValue;
|
||||||
env::var($env_name)
|
env::var($env_name)
|
||||||
.map(|val| EnvValue::from(val).into())
|
.map(|val| __itconfig_variable_helper!(val))
|
||||||
.unwrap_or_else(|_| env_or!(@$token $env_name, $default))
|
.unwrap_or_else(|_| __itconfig_variable_helper!(@$token $env_name, $default))
|
||||||
}};
|
}};
|
||||||
|
|
||||||
(@default $env_name:expr, $default:expr) => {{
|
// Returns converted env variable
|
||||||
|
($(@default $env_name:expr,)? $default:expr) => {{
|
||||||
|
EnvValue::from($default.to_string()).into()
|
||||||
|
}};
|
||||||
|
|
||||||
|
// Set default value for env variable and returns default
|
||||||
|
(@setenv $env_name:expr, $default:expr) => {{
|
||||||
env::set_var($env_name, $default.to_string());
|
env::set_var($env_name, $default.to_string());
|
||||||
$default
|
__itconfig_variable_helper!($default)
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
// Make panic for env variable
|
||||||
(@panic $env_name:expr, $default:expr) => {
|
(@panic $env_name:expr, $default:expr) => {
|
||||||
panic!($default);
|
panic!($default);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Invalid syntax
|
||||||
|
($($tokens:tt)*) => {
|
||||||
|
__itconfig_env_or_invalid_syntax!();
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
use std::env;
|
use std::env;
|
||||||
|
use std::env::VarError;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate itconfig;
|
extern crate itconfig;
|
||||||
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic]
|
#[should_panic(expected = "Cannot read \"MISS_VARIABLE\" environment variable")]
|
||||||
fn should_panic_if_miss_env_variable() {
|
fn should_panic_if_miss_env_variable() {
|
||||||
config! {
|
config! {
|
||||||
MISS_VARIABLE: bool,
|
MISS_VARIABLE: bool,
|
||||||
|
@ -55,13 +56,15 @@ fn different_types_with_default_value() {
|
||||||
config! {
|
config! {
|
||||||
NUMBER: i32 => 30,
|
NUMBER: i32 => 30,
|
||||||
BOOL: bool => true,
|
BOOL: bool => true,
|
||||||
|
STR: String => "str",
|
||||||
STRING: String => "string".to_string(),
|
STRING: String => "string".to_string(),
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg::init();
|
cfg::init();
|
||||||
assert_eq!(cfg::NUMBER(), 30);
|
assert_eq!(cfg::NUMBER(), 30);
|
||||||
assert_eq!(cfg::BOOL(), true);
|
assert_eq!(cfg::BOOL(), true);
|
||||||
assert_eq!(cfg::STRING(), "string");
|
assert_eq!(cfg::STR(), "str".to_string());
|
||||||
|
assert_eq!(cfg::STRING(), "string".to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -157,12 +160,12 @@ fn change_configuration_module_name() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn configuration_with_namespace() {
|
fn configuration_with_namespace() {
|
||||||
env::set_var("POSTGRES_HOST", "t");
|
env::set_var("DB_HOST", "t");
|
||||||
|
|
||||||
config! {
|
config! {
|
||||||
DEBUG: bool => true,
|
DEBUG: bool => true,
|
||||||
|
|
||||||
POSTGRES {
|
DB {
|
||||||
HOST: bool,
|
HOST: bool,
|
||||||
PORT: bool => true,
|
PORT: bool => true,
|
||||||
USERNAME: bool => true,
|
USERNAME: bool => true,
|
||||||
|
@ -173,8 +176,7 @@ fn configuration_with_namespace() {
|
||||||
|
|
||||||
cfg::init();
|
cfg::init();
|
||||||
assert_eq!(cfg::DEBUG(), true);
|
assert_eq!(cfg::DEBUG(), true);
|
||||||
assert_eq!(cfg::POSTGRES::HOST(), true);
|
assert_eq!(cfg::DB::HOST(), true);
|
||||||
env::remove_var("POSTGRES_HOST");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -194,8 +196,6 @@ fn configuration_variables_and_namespace_in_lowercase() {
|
||||||
cfg::init();
|
cfg::init();
|
||||||
assert_eq!(cfg::testing(), true);
|
assert_eq!(cfg::testing(), true);
|
||||||
assert_eq!(cfg::namespace::foo(), true);
|
assert_eq!(cfg::namespace::foo(), true);
|
||||||
env::remove_var("TESTING");
|
|
||||||
env::remove_var("NAMESPACE_FOO");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -216,7 +216,6 @@ fn custom_environment_name_for_variable() {
|
||||||
cfg::init();
|
cfg::init();
|
||||||
assert_eq!(cfg::PER_PAGE(), 95);
|
assert_eq!(cfg::PER_PAGE(), 95);
|
||||||
assert_eq!(cfg::APP::RECIPES_PER_PAGE(), 95);
|
assert_eq!(cfg::APP::RECIPES_PER_PAGE(), 95);
|
||||||
env::remove_var("MY_CUSTOM_NAME");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -239,13 +238,12 @@ fn stranger_meta_data() {
|
||||||
|
|
||||||
#[cfg(feature = "postgres")]
|
#[cfg(feature = "postgres")]
|
||||||
assert_eq!(cfg::DATABASE_URL(), "95");
|
assert_eq!(cfg::DATABASE_URL(), "95");
|
||||||
env::remove_var("MY_CUSTOM_NAME");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn setting_default_env_variable() {
|
fn setting_default_env_variable() {
|
||||||
config! {
|
config! {
|
||||||
DEFAULT_ENV_STRING: String => "localhost".to_string(),
|
DEFAULT_ENV_STRING: String => "localhost",
|
||||||
DEFAULT_ENV_BOOLEAN: bool => true,
|
DEFAULT_ENV_BOOLEAN: bool => true,
|
||||||
DEFAULT_ENV_UINT: u32 => 40,
|
DEFAULT_ENV_UINT: u32 => 40,
|
||||||
DEFAULT_ENV_FLOAT: f64 => 40.9,
|
DEFAULT_ENV_FLOAT: f64 => 40.9,
|
||||||
|
@ -259,3 +257,135 @@ fn setting_default_env_variable() {
|
||||||
assert_eq!(env::var("DEFAULT_ENV_FLOAT"), Ok("40.9".to_string()));
|
assert_eq!(env::var("DEFAULT_ENV_FLOAT"), Ok("40.9".to_string()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn concatenate_environment_variables() {
|
||||||
|
env::set_var("POSTGRES_USERNAME", "user");
|
||||||
|
env::set_var("POSTGRES_PASSWORD", "pass");
|
||||||
|
env::set_var("POSTGRES_HOST", "localhost");
|
||||||
|
env::set_var("POSTGRES_DB", "test");
|
||||||
|
|
||||||
|
config! {
|
||||||
|
DATABASE_URL < (
|
||||||
|
"postgres://",
|
||||||
|
POSTGRES_USERNAME,
|
||||||
|
":",
|
||||||
|
POSTGRES_PASSWORD,
|
||||||
|
"@",
|
||||||
|
POSTGRES_HOST,
|
||||||
|
"/",
|
||||||
|
POSTGRES_DB,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg::init();
|
||||||
|
assert_eq!(cfg::DATABASE_URL(), String::from("postgres://user:pass@localhost/test"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn setting_default_concat_env_variable() {
|
||||||
|
env::set_var("SETTING_DEFAULT_CONCAT_ENV_VARIABLE", "custom");
|
||||||
|
|
||||||
|
config! {
|
||||||
|
DEFAULT_CONCAT_ENV < (
|
||||||
|
"string",
|
||||||
|
"/",
|
||||||
|
SETTING_DEFAULT_CONCAT_ENV_VARIABLE,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg::init();
|
||||||
|
assert_eq!(env::var("DEFAULT_CONCAT_ENV"), Ok("string/custom".to_string()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic(expected = "Cannot read \"PG_USERNAME\" environment variable")]
|
||||||
|
fn concatenate_not_defined_environment_variables() {
|
||||||
|
config! {
|
||||||
|
DATABASE_URL < (
|
||||||
|
"postgres://",
|
||||||
|
PG_USERNAME,
|
||||||
|
":",
|
||||||
|
PG_PASSWORD,
|
||||||
|
"@",
|
||||||
|
PG_HOST,
|
||||||
|
"/",
|
||||||
|
PG_DB,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
cfg::init();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn default_value_for_concatenate_env_parameter() {
|
||||||
|
config! {
|
||||||
|
CONCATENATED_DATABASE_URL < (
|
||||||
|
"postgres://",
|
||||||
|
NOT_DEFINED_PG_USERNAME => "user",
|
||||||
|
":",
|
||||||
|
NOT_DEFINED_PG_PASSWORD => "pass",
|
||||||
|
"@",
|
||||||
|
NOT_DEFINED_PG_HOST => "localhost:5432",
|
||||||
|
"/",
|
||||||
|
NOT_DEFINED_PG_DB => "test",
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg::init();
|
||||||
|
assert_eq!(
|
||||||
|
env::var("CONCATENATED_DATABASE_URL"),
|
||||||
|
Ok("postgres://user:pass@localhost:5432/test".to_string())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn envname_meta_for_concatenated_env_variable() {
|
||||||
|
config! {
|
||||||
|
#[env_name = "CUSTOM_CONCAT_ENVNAME"]
|
||||||
|
CONCAT_ENVVAR < (
|
||||||
|
"postgres://",
|
||||||
|
NOT_DEFINED_PG_USERNAME => "user",
|
||||||
|
":",
|
||||||
|
NOT_DEFINED_PG_PASSWORD => "pass",
|
||||||
|
"@",
|
||||||
|
NOT_DEFINED_PG_HOST => "localhost:5432",
|
||||||
|
"/",
|
||||||
|
NOT_DEFINED_PG_DB => "test",
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg::init();
|
||||||
|
assert_eq!(
|
||||||
|
env::var("CUSTOM_CONCAT_ENVNAME"),
|
||||||
|
Ok("postgres://user:pass@localhost:5432/test".to_string())
|
||||||
|
);
|
||||||
|
assert_eq!(env::var("CONCAT_ENVVAR"), Err(VarError::NotPresent));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn concatenated_environment_variable_in_namespace() {
|
||||||
|
config! {
|
||||||
|
CONCATED_NAMESPACE {
|
||||||
|
CONCAT_ENVVAR < (
|
||||||
|
"postgres://",
|
||||||
|
NOT_DEFINED_PG_USERNAME => "user",
|
||||||
|
":",
|
||||||
|
NOT_DEFINED_PG_PASSWORD => "pass",
|
||||||
|
"@",
|
||||||
|
NOT_DEFINED_PG_HOST => "localhost:5432",
|
||||||
|
"/",
|
||||||
|
NOT_DEFINED_PG_DB => "test",
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg::init();
|
||||||
|
assert_eq!(
|
||||||
|
env::var("CONCATED_NAMESPACE_CONCAT_ENVVAR"),
|
||||||
|
Ok("postgres://user:pass@localhost:5432/test".to_string())
|
||||||
|
);
|
||||||
|
assert_eq!(env::var("CONCAT_ENVVAR"), Err(VarError::NotPresent));
|
||||||
|
}
|
||||||
|
|
Reference in a new issue