Merge pull request #3 from icetemple/custom-env

Custom env
This commit is contained in:
Dmitriy Pleshevskiy 2019-12-26 08:31:44 +03:00 committed by GitHub
commit 51ebd01ea0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 132 additions and 21 deletions

View file

@ -1,7 +1,7 @@
# itconfig # itconfig
[![Build Status](https://travis-ci.org/icetemple/itconfig-rs.svg?branch=master)](https://travis-ci.org/icetemple/itconfig-rs) [![Build Status](https://travis-ci.org/icetemple/itconfig-rs.svg?branch=master)](https://travis-ci.org/icetemple/itconfig-rs)
[![Documentation](https://docs.rs/itconfig/badge.svg)](https://docs.rs/itconfig) [![Documentation](https://docs.rs/itconfig/badge.svg)](https://docs.rs/itconfig)
[![Crates.io](https://img.shields.io/badge/crates.io-v0.3.0-orange.svg?longCache=true)](https://crates.io/crates/itconfig) [![Crates.io](https://img.shields.io/badge/crates.io-v0.4.0-orange.svg?longCache=true)](https://crates.io/crates/itconfig)
Easy build a configs from environment variables and use it in globally. Easy build a configs from environment variables and use it in globally.
@ -12,22 +12,28 @@ We recommend you start with the [documentation].
```rust ```rust
#[macro_use] extern crate itconfig; #[macro_use] extern crate itconfig;
use dotenv::dotenv; use std::env;
//use dotenv::dotenv;
config! { config! {
DEBUG: bool => true, DEBUG: bool => true,
HOST: String => "127.0.0.1".to_string(), HOST: String => "127.0.0.1".to_string(),
NAMESPACE { NAMESPACE {
FOO: bool => true, #[env_name = "MY_CUSTOM_NAME"]
FOO: bool,
BAR: i32 => 10, BAR: i32 => 10,
} }
} }
fn main () { fn main () {
dotenv().ok(); // dotenv().ok();
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);
} }
``` ```
@ -41,7 +47,7 @@ cargo test
## Roadmap ## Roadmap
* [x] Add namespace for variables * [x] Add namespace for variables
* [ ] Custom env name * [x] Custom env name
* [ ] Add if condition for feature variables * [ ] Add if condition for feature variables

View file

@ -1,6 +1,6 @@
[package] [package]
name = "itconfig" name = "itconfig"
version = "0.3.0" version = "0.4.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"]

View file

@ -9,22 +9,28 @@ We recommend you start with the [documentation].
```rust ```rust
#[macro_use] extern crate itconfig; #[macro_use] extern crate itconfig;
// use dotenv::dotenv; use std::env;
//use dotenv::dotenv;
config! { config! {
DEBUG: bool => true, DEBUG: bool => true,
HOST: String => "127.0.0.1".to_string(), HOST: String => "127.0.0.1".to_string(),
NAMESPACE { NAMESPACE {
FOO: bool => true, #[env_name = "MY_CUSTOM_NAME"]
FOO: bool,
BAR: i32 => 10, BAR: i32 => 10,
} }
} }
fn main () { fn main () {
// dotenv().ok(); // dotenv().ok();
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);
} }
``` ```
@ -32,7 +38,7 @@ fn main () {
## Roadmap ## Roadmap
* [x] Add namespace for variables * [x] Add namespace for variables
* [ ] Custom env name * [x] Custom env name
* [ ] Add if condition for feature variables * [ ] Add if condition for feature variables

View file

@ -7,6 +7,7 @@
//! //!
//! ```rust //! ```rust
//! #[macro_use] extern crate itconfig; //! #[macro_use] extern crate itconfig;
//! use std::env;
//! // use dotenv::dotenv; //! // use dotenv::dotenv;
//! //!
//! config! { //! config! {
@ -14,15 +15,20 @@
//! HOST: String => "127.0.0.1".to_string(), //! HOST: String => "127.0.0.1".to_string(),
//! //!
//! NAMESPACE { //! NAMESPACE {
//! FOO: bool => true, //! #[env_name = "MY_CUSTOM_NAME"]
//! FOO: bool,
//!
//! BAR: i32 => 10, //! BAR: i32 => 10,
//! } //! }
//! } //! }
//! //!
//! fn main () { //! fn main () {
//! // dotenv().ok(); //! // dotenv().ok();
//! 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);
//! } //! }
//! ``` //! ```
@ -142,6 +148,30 @@ impl From<EnvValue> for String {
/// # cfg::init() /// # cfg::init()
/// ``` /// ```
/// ///
/// If you want to read custom env name for variable you can change it manually.
///
/// **A variable in the nameespace will lose environment prefix**
///
/// ```rust
/// # #[macro_use] extern crate itconfig;
/// # use std::env;
/// env::set_var("MY_CUSTOM_NAME", "95");
///
/// config! {
/// #[env_name = "MY_CUSTOM_NAME"]
/// PER_PAGE: i32,
///
/// APP {
/// #[env_name = "MY_CUSTOM_NAME"]
/// RECIPES_PER_PAGE: i32,
/// }
/// }
///
/// cfg::init();
/// assert_eq!(cfg::PER_PAGE(), 95);
/// assert_eq!(cfg::APP::RECIPES_PER_PAGE(), 95);
/// ```
///
/// ///
/// This module will also contain helper method: /// This module will also contain helper method:
/// ///
@ -216,6 +246,7 @@ macro_rules! __itconfig_parse_module {
variables = [], variables = [],
namespaces = [], namespaces = [],
module = { module = {
env_prefix = "",
name = $name, name = $name,
}, },
} }
@ -242,10 +273,11 @@ macro_rules! __itconfig_parse_variables {
__itconfig_parse_variables! { __itconfig_parse_variables! {
tokens = [$($ns_tokens)*], tokens = [$($ns_tokens)*],
variables = [], variables = [],
callback = { module = {
current_namespace = { env_prefix = concat!(stringify!($ns_name), "_"),
name = $ns_name, name = $ns_name,
}, },
callback = {
tokens = [$($rest)*], tokens = [$($rest)*],
$($args)* $($args)*
}, },
@ -255,6 +287,7 @@ macro_rules! __itconfig_parse_variables {
// Find variable with default value // Find variable with default value
( (
tokens = [ tokens = [
$(#$meta:tt)*
$name:ident : $ty:ty => $default:expr, $name:ident : $ty:ty => $default:expr,
$($rest:tt)* $($rest:tt)*
], ],
@ -262,6 +295,7 @@ macro_rules! __itconfig_parse_variables {
) => { ) => {
__itconfig_parse_variables! { __itconfig_parse_variables! {
current_variable = { current_variable = {
unparsed_meta = [$(#$meta)*],
name = $name, name = $name,
ty = $ty, ty = $ty,
default = $default, default = $default,
@ -274,6 +308,7 @@ macro_rules! __itconfig_parse_variables {
// Find variable without default value // Find variable without default value
( (
tokens = [ tokens = [
$(#$meta:tt)*
$name:ident : $ty:ty, $name:ident : $ty:ty,
$($rest:tt)* $($rest:tt)*
], ],
@ -281,6 +316,7 @@ macro_rules! __itconfig_parse_variables {
) => { ) => {
__itconfig_parse_variables! { __itconfig_parse_variables! {
current_variable = { current_variable = {
unparsed_meta = [$(#$meta)*],
name = $name, name = $name,
ty = $ty, ty = $ty,
}, },
@ -289,9 +325,32 @@ macro_rules! __itconfig_parse_variables {
} }
}; };
(
current_variable = {
unparsed_meta = [
#[env_name = $env_name:expr]
$($meta:tt)*
],
name = $name:ident,
$($current_variable:tt)*
},
$($args:tt)*
) => {
__itconfig_parse_variables! {
current_variable = {
unparsed_meta = [$($meta)*],
name = $name,
env_name = $env_name,
$($current_variable)*
},
$($args)*
}
};
// Done parsing variable // Done parsing variable
( (
current_variable = { current_variable = {
unparsed_meta = [],
$($current_variable:tt)* $($current_variable:tt)*
}, },
tokens = $tokens:tt, tokens = $tokens:tt,
@ -309,10 +368,10 @@ macro_rules! __itconfig_parse_variables {
( (
tokens = [], tokens = [],
variables = $ns_variables:tt, variables = $ns_variables:tt,
callback = { module = {
current_namespace = {
$($current_namespace:tt)* $($current_namespace:tt)*
}, },
callback = {
tokens = $tokens:tt, tokens = $tokens:tt,
variables = $variables:tt, variables = $variables:tt,
namespaces = [$($namespaces:tt,)*], namespaces = [$($namespaces:tt,)*],
@ -361,9 +420,11 @@ macro_rules! __itconfig_impl {
name = $ns_var_name:tt, name = $ns_var_name:tt,
$($ns_variables:tt)* $($ns_variables:tt)*
},)*], },)*],
env_prefix = $ns_env_prefix:expr,
name = $ns_name:ident, name = $ns_name:ident,
},)*], },)*],
module = { module = {
env_prefix = $env_prefix:expr,
name = $mod_name:ident, name = $mod_name:ident,
}, },
) => { ) => {
@ -379,7 +440,7 @@ macro_rules! __itconfig_impl {
$(__itconfig_variable! { $(__itconfig_variable! {
name = $ns_var_name, name = $ns_var_name,
env_name = concat!(stringify!($ns_name), "_", stringify!($ns_var_name)), env_prefix = $ns_env_prefix,
$($ns_variables)* $($ns_variables)*
})* })*
} }
@ -393,7 +454,7 @@ macro_rules! __itconfig_impl {
$(__itconfig_variable! { $(__itconfig_variable! {
name = $var_name, name = $var_name,
env_name = stringify!($var_name), env_prefix = $env_prefix,
$($variable)* $($variable)*
})* })*
} }
@ -409,30 +470,47 @@ macro_rules! __itconfig_impl {
#[macro_export] #[macro_export]
#[doc(hidden)] #[doc(hidden)]
macro_rules! __itconfig_variable { macro_rules! __itconfig_variable {
(
name = $name:ident,
env_prefix = $env_prefix:expr,
ty = $ty:ty,
$($args:tt)*
) => {
__itconfig_variable! {
name = $name,
env_prefix = $env_prefix,
env_name = concat!($env_prefix, stringify!($name)).to_uppercase(),
ty = $ty,
$($args)*
}
};
// Add method without default value // Add method without default value
( (
name = $name:ident, name = $name:ident,
env_prefix = $env_prefix:expr,
env_name = $env_name:expr, env_name = $env_name:expr,
ty = $ty:ty, ty = $ty:ty,
) => { ) => {
__itconfig_variable! { __itconfig_variable! {
name = $name, name = $name,
env_prefix = $env_prefix,
env_name = $env_name, env_name = $env_name,
ty = $ty, ty = $ty,
default = panic!(format!(r#"Cannot read "{}" environment variable"#, default = panic!(format!(r#"Cannot read "{}" environment variable"#, $env_name)),
$env_name.to_uppercase())),
} }
}; };
// Add method with default value // Add method with default value
( (
name = $name:ident, name = $name:ident,
env_prefix = $env_prefix:expr,
env_name = $env_name:expr, env_name = $env_name:expr,
ty = $ty:ty, ty = $ty:ty,
default = $default:expr, default = $default:expr,
) => { ) => {
pub fn $name() -> $ty { pub fn $name() -> $ty {
env::var($env_name.to_uppercase()) env::var($env_name)
.map(|val| EnvValue::from(val).into()) .map(|val| EnvValue::from(val).into())
.unwrap_or_else(|_| $default) .unwrap_or_else(|_| $default)
} }

View file

@ -197,3 +197,24 @@ fn configuration_variables_and_namespace_in_lowercase() {
env::remove_var("TESTING"); env::remove_var("TESTING");
env::remove_var("NAMESPACE_FOO"); env::remove_var("NAMESPACE_FOO");
} }
#[test]
fn custom_environment_name_for_variable() {
env::set_var("MY_CUSTOM_NAME", "95");
config! {
#[env_name = "MY_CUSTOM_NAME"]
PER_PAGE: i32,
APP {
#[env_name = "MY_CUSTOM_NAME"]
RECIPES_PER_PAGE: i32,
}
}
cfg::init();
assert_eq!(cfg::PER_PAGE(), 95);
assert_eq!(cfg::APP::RECIPES_PER_PAGE(), 95);
env::remove_var("MY_CUSTOM_NAME");
}