From b305b7334b39465396a9377099b4cb695164835e Mon Sep 17 00:00:00 2001 From: Dmitriy Pleshevskiy Date: Fri, 27 Dec 2019 23:57:13 +0300 Subject: [PATCH] feat: add custom meta for vars --- Cargo.toml | 2 +- README.md | 7 +++- itconfig/Cargo.toml | 7 ++-- itconfig/README.md | 7 +++- itconfig/src/lib.rs | 59 ++++++++++++++++++++++++++-- itconfig_tests/Cargo.toml | 2 +- itconfig_tests/tests/config_macro.rs | 23 +++++++++++ 7 files changed, 97 insertions(+), 10 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c77a2ad..ff52a9d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,4 +2,4 @@ members = [ "itconfig", "itconfig_tests" -] \ No newline at end of file +] diff --git a/README.md b/README.md index 970ab11..0d03f32 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,10 @@ config! { FOO: bool, BAR: i32 => 10, + + #[cfg(feature = "feature")] + #[env_name = "POSTGRES_CONNECTION_STRING"] + DATABASE_URL: String } } @@ -48,7 +52,8 @@ cargo test * [x] Add namespace for variables * [x] Custom env name -* [ ] Add if condition for feature variables +* [x] Support feature config and other meta directives +* [ ] Concat env variables to one variable ## License diff --git a/itconfig/Cargo.toml b/itconfig/Cargo.toml index de9f886..6575af8 100644 --- a/itconfig/Cargo.toml +++ b/itconfig/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "itconfig" -version = "0.4.0" +version = "0.5.0" authors = ["Dmitriy Pleshevskiy "] description = "Easy build a configs from environment variables and use it in globally." categories = ["config", "web-programming"] @@ -14,7 +14,8 @@ readme = "README.md" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html -[badges.travis-ci] -repository = "icetemple/itconfig-rs" +[badges] +travis-ci = { repository = "icetemple/itconfig-rs" } +maintenance = { status = "actively-developed" } [dependencies] diff --git a/itconfig/README.md b/itconfig/README.md index ac38888..7b87e3e 100644 --- a/itconfig/README.md +++ b/itconfig/README.md @@ -21,6 +21,10 @@ config! { FOO: bool, BAR: i32 => 10, + + #[cfg(feature = "feature")] + #[env_name = "POSTGRES_CONNECTION_STRING"] + DATABASE_URL: String } } @@ -39,7 +43,8 @@ fn main () { * [x] Add namespace for variables * [x] Custom env name -* [ ] Add if condition for feature variables +* [x] Support feature config and other meta directives +* [ ] Concat env variables to one variable ## License diff --git a/itconfig/src/lib.rs b/itconfig/src/lib.rs index 3cb50d7..0d1d734 100644 --- a/itconfig/src/lib.rs +++ b/itconfig/src/lib.rs @@ -172,6 +172,20 @@ impl From for String { /// assert_eq!(cfg::APP::RECIPES_PER_PAGE(), 95); /// ``` /// +/// Also you can add custom meta for each variable. For example feature configurations. +/// +/// ```rust +/// # #[macro_use] extern crate itconfig; +/// config! { +/// #[cfg(feature = "postgres")] +/// DATABASE_URL: String, +/// +/// #[cfg(not(feature = "postgres"))] +/// DATABASE_URL: String, +/// } +/// # fn main() {} +/// ``` +/// /// /// This module will also contain helper method: /// @@ -296,6 +310,7 @@ macro_rules! __itconfig_parse_variables { __itconfig_parse_variables! { current_variable = { unparsed_meta = [$(#$meta)*], + meta = [], name = $name, ty = $ty, default = $default, @@ -317,6 +332,7 @@ macro_rules! __itconfig_parse_variables { __itconfig_parse_variables! { current_variable = { unparsed_meta = [$(#$meta)*], + meta = [], name = $name, ty = $ty, }, @@ -325,12 +341,14 @@ macro_rules! __itconfig_parse_variables { } }; + // Find meta with custom env name ( current_variable = { unparsed_meta = [ #[env_name = $env_name:expr] - $($meta:tt)* + $($rest:tt)* ], + meta = $meta:tt, name = $name:ident, $($current_variable:tt)* }, @@ -338,7 +356,8 @@ macro_rules! __itconfig_parse_variables { ) => { __itconfig_parse_variables! { current_variable = { - unparsed_meta = [$($meta)*], + unparsed_meta = [$($rest)*], + meta = $meta, name = $name, env_name = $env_name, $($current_variable)* @@ -347,6 +366,30 @@ macro_rules! __itconfig_parse_variables { } }; + // Find stranger meta + ( + current_variable = { + unparsed_meta = [ + #$stranger_meta:tt + $($rest:tt)* + ], + meta = [$(#$meta:tt,)*], + name = $name:ident, + $($current_variable:tt)* + }, + $($args:tt)* + ) => { + __itconfig_parse_variables! { + current_variable = { + unparsed_meta = [$($rest)*], + meta = [$(#$meta,)* #$stranger_meta,], + name = $name, + $($current_variable)* + }, + $($args)* + } + }; + // Done parsing variable ( current_variable = { @@ -412,12 +455,14 @@ macro_rules! __itconfig_parse_variables { macro_rules! __itconfig_impl { ( variables = [$({ + meta = $var_meta:tt, name = $var_name:ident, $($variable:tt)* },)*], namespaces = [$({ variables = [$({ - name = $ns_var_name:tt, + meta = $ns_var_meta:tt, + name = $ns_var_name:ident, $($ns_variables:tt)* },)*], env_prefix = $ns_env_prefix:expr, @@ -439,6 +484,7 @@ macro_rules! __itconfig_impl { use $crate::EnvValue; $(__itconfig_variable! { + meta = $ns_var_meta, name = $ns_var_name, env_prefix = $ns_env_prefix, $($ns_variables)* @@ -453,6 +499,7 @@ macro_rules! __itconfig_impl { } $(__itconfig_variable! { + meta = $var_meta, name = $var_name, env_prefix = $env_prefix, $($variable)* @@ -471,12 +518,14 @@ macro_rules! __itconfig_impl { #[doc(hidden)] macro_rules! __itconfig_variable { ( + meta = $meta:tt, name = $name:ident, env_prefix = $env_prefix:expr, ty = $ty:ty, $($args:tt)* ) => { __itconfig_variable! { + meta = $meta, name = $name, env_prefix = $env_prefix, env_name = concat!($env_prefix, stringify!($name)).to_uppercase(), @@ -487,12 +536,14 @@ macro_rules! __itconfig_variable { // Add method without default value ( + meta = $meta:tt, name = $name:ident, env_prefix = $env_prefix:expr, env_name = $env_name:expr, ty = $ty:ty, ) => { __itconfig_variable! { + meta = $meta, name = $name, env_prefix = $env_prefix, env_name = $env_name, @@ -503,12 +554,14 @@ macro_rules! __itconfig_variable { // Add method with default value ( + meta = [$(#$meta:tt,)*], name = $name:ident, env_prefix = $env_prefix:expr, env_name = $env_name:expr, ty = $ty:ty, default = $default:expr, ) => { + $(#$meta)* pub fn $name() -> $ty { env::var($env_name) .map(|val| EnvValue::from(val).into()) diff --git a/itconfig_tests/Cargo.toml b/itconfig_tests/Cargo.toml index 6cb338f..6cb956b 100644 --- a/itconfig_tests/Cargo.toml +++ b/itconfig_tests/Cargo.toml @@ -9,4 +9,4 @@ publish = false # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -itconfig = { path = '../itconfig' } \ No newline at end of file +itconfig = { path = '../itconfig' } diff --git a/itconfig_tests/tests/config_macro.rs b/itconfig_tests/tests/config_macro.rs index 9b9ac87..c3881a0 100644 --- a/itconfig_tests/tests/config_macro.rs +++ b/itconfig_tests/tests/config_macro.rs @@ -217,4 +217,27 @@ fn custom_environment_name_for_variable() { assert_eq!(cfg::PER_PAGE(), 95); assert_eq!(cfg::APP::RECIPES_PER_PAGE(), 95); env::remove_var("MY_CUSTOM_NAME"); +} + +#[test] +fn stranger_meta_data() { + env::set_var("MY_CUSTOM_NAME", "95"); + + config! { + #[cfg(feature = "postgres")] + #[env_name = "MY_CUSTOM_NAME"] + DATABASE_URL: String, + + #[cfg(not(feature = "postgres"))] + #[env_name = "MY_CUSTOM_NAME"] + DATABASE_URL: i32, + } + + cfg::init(); + #[cfg(not(feature = "postgres"))] + assert_eq!(cfg::DATABASE_URL(), 95); + + #[cfg(feature = "postgres")] + assert_eq!(cfg::DATABASE_URL(), "95"); + env::remove_var("MY_CUSTOM_NAME"); } \ No newline at end of file