parent
ee2f098f4d
commit
175798acf3
7 changed files with 232 additions and 30 deletions
|
@ -14,8 +14,9 @@ criterion = "0.3.1"
|
|||
lazy_static = "1.4.0"
|
||||
|
||||
[features]
|
||||
default = ["meta_namespace"]
|
||||
default = ["meta_namespace", "static"]
|
||||
meta_namespace = []
|
||||
static = ["itconfig/static"]
|
||||
|
||||
[[bench]]
|
||||
name = "main_benches"
|
||||
|
|
|
@ -3,11 +3,13 @@ use std::env;
|
|||
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
#[macro_use]
|
||||
extern crate itconfig;
|
||||
|
||||
|
||||
|
||||
fn setup_env_var(initial: &String) {
|
||||
env::set_var("TEST", initial);
|
||||
fn setup_env_var(key: &'static str, initial: String) {
|
||||
env::set_var(key, initial);
|
||||
}
|
||||
|
||||
|
||||
|
@ -26,33 +28,66 @@ fn lazy_get_env() -> u32 {
|
|||
|
||||
|
||||
fn source_vs_lazy(c: &mut Criterion) {
|
||||
let source = Fun::new("source", |b, initial: &String| {
|
||||
setup_env_var(initial);
|
||||
let int: u32 = initial.parse().unwrap();
|
||||
setup_env_var("TEST", "1".to_string());
|
||||
|
||||
let source = Fun::new("source", |b, _| {
|
||||
b.iter(move || {
|
||||
assert_eq!(source_get_env(), int)
|
||||
assert_eq!(source_get_env(), 1)
|
||||
})
|
||||
});
|
||||
let lazy = Fun::new("lazy", |b, initial: &String| {
|
||||
setup_env_var(initial);
|
||||
let int: u32 = initial.parse().unwrap();
|
||||
|
||||
let lazy = Fun::new("lazy", |b, _| {
|
||||
b.iter(move || {
|
||||
assert_eq!(lazy_get_env(), int);
|
||||
assert_eq!(lazy_get_env(), 1);
|
||||
})
|
||||
});
|
||||
|
||||
let funcs = vec![source, lazy];
|
||||
|
||||
c.bench_functions("get_env", funcs, "1".to_string());
|
||||
c.bench_functions("get_env", vec![source, lazy], 0);
|
||||
}
|
||||
|
||||
|
||||
fn source_macro_vs_lazy_macro(c: &mut Criterion) {
|
||||
config! {
|
||||
TEST: &'static str,
|
||||
TEST_WITH_DEFAULT: &'static str => "default",
|
||||
|
||||
static LAZY_TEST: &'static str,
|
||||
static LAZY_TEST_WITH_DEFAULT: &'static str => "default",
|
||||
}
|
||||
|
||||
setup_env_var("TEST", "test".to_string());
|
||||
setup_env_var("LAZY_TEST", "test".to_string());
|
||||
|
||||
let source = Fun::new("source", |b, _| {
|
||||
b.iter(move || {
|
||||
assert_eq!(cfg::TEST(), "test");
|
||||
})
|
||||
});
|
||||
let lazy = Fun::new("lazy", |b, _| {
|
||||
b.iter(move || {
|
||||
assert_eq!(cfg::LAZY_TEST(), "test");
|
||||
})
|
||||
});
|
||||
let source_with_default = Fun::new("source_with_default", |b, _| {
|
||||
b.iter(move || {
|
||||
assert_eq!(cfg::TEST_WITH_DEFAULT(), "default");
|
||||
})
|
||||
});
|
||||
let lazy_with_default = Fun::new("lazy_with_default", |b, _| {
|
||||
b.iter(move || {
|
||||
assert_eq!(cfg::LAZY_TEST_WITH_DEFAULT(), "default");
|
||||
})
|
||||
});
|
||||
|
||||
let funcs = vec![source, lazy, source_with_default, lazy_with_default];
|
||||
|
||||
c.bench_functions("macro", funcs, 0);
|
||||
}
|
||||
|
||||
|
||||
criterion_group! {
|
||||
benches,
|
||||
source_vs_lazy,
|
||||
source_macro_vs_lazy_macro,
|
||||
}
|
||||
|
||||
criterion_main!(benches);
|
||||
|
|
|
@ -422,3 +422,51 @@ fn concatenated_environment_variable_in_namespace() {
|
|||
);
|
||||
assert_eq!(env::var("CONCAT_ENVVAR"), Err(VarError::NotPresent));
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "static")]
|
||||
fn static_variables() {
|
||||
config! {
|
||||
static STATIC_STR => "test",
|
||||
static STATIC_STRING: String => "test",
|
||||
static STATIC_I8: i8 => 1,
|
||||
static STATIC_I16: i16 => 1,
|
||||
static STATIC_I32: i32 => 1,
|
||||
static STATIC_I64: i64 => 1,
|
||||
static STATIC_I128: i128 => 1,
|
||||
static STATIC_ISIZE: isize => 1,
|
||||
static STATIC_U8: u8 => 1,
|
||||
static STATIC_U16: u16 => 1,
|
||||
static STATIC_U32: u32 => 1,
|
||||
static STATIC_U64: u64 => 1,
|
||||
static STATIC_U128: u128 => 1,
|
||||
static STATIC_USIZE: usize => 1,
|
||||
static STATIC_F32: f32 => 1,
|
||||
static STATIC_F64: f64 => 1,
|
||||
static STATIC_CONCAT_VARIABLE < (
|
||||
"static ",
|
||||
STATIC_CONCAT_PART => "part",
|
||||
),
|
||||
}
|
||||
|
||||
cfg::init();
|
||||
|
||||
assert_eq!(cfg::STATIC_STR(), "test");
|
||||
assert_eq!(cfg::STATIC_STRING(), "test".to_string());
|
||||
assert_eq!(cfg::STATIC_I8(), 1);
|
||||
assert_eq!(cfg::STATIC_I16(), 1);
|
||||
assert_eq!(cfg::STATIC_I32(), 1);
|
||||
assert_eq!(cfg::STATIC_I64(), 1);
|
||||
assert_eq!(cfg::STATIC_I128(), 1);
|
||||
assert_eq!(cfg::STATIC_ISIZE(), 1);
|
||||
assert_eq!(cfg::STATIC_U8(), 1);
|
||||
assert_eq!(cfg::STATIC_U16(), 1);
|
||||
assert_eq!(cfg::STATIC_U32(), 1);
|
||||
assert_eq!(cfg::STATIC_U64(), 1);
|
||||
assert_eq!(cfg::STATIC_U128(), 1);
|
||||
assert_eq!(cfg::STATIC_USIZE(), 1);
|
||||
assert_eq!(cfg::STATIC_F32(), 1.0);
|
||||
assert_eq!(cfg::STATIC_F64(), 1.0);
|
||||
assert_eq!(cfg::STATIC_CONCAT_VARIABLE(), "static part".to_string())
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "itconfig"
|
||||
version = "0.10.2"
|
||||
version = "0.11.0"
|
||||
authors = ["Dmitriy Pleshevskiy <dmitriy@ideascup.me>"]
|
||||
description = "Easy build a configs from environment variables and use it in globally."
|
||||
categories = ["config", "web-programming"]
|
||||
|
@ -16,11 +16,14 @@ readme = "README.md"
|
|||
|
||||
[dependencies]
|
||||
failure = { version = "0.1.6", features = ["derive"]}
|
||||
lazy_static = { version = "1.4.0", optional = true }
|
||||
serde_json = { version = "1.0.44", optional = true }
|
||||
|
||||
[features]
|
||||
default = ["macro", "primitives"]
|
||||
default = ["macro", "primitives", "static"]
|
||||
|
||||
macro = []
|
||||
static = ["lazy_static"]
|
||||
|
||||
array = ["serde_json"]
|
||||
|
||||
|
|
|
@ -119,6 +119,15 @@ impl FromEnvString for String {
|
|||
}
|
||||
|
||||
|
||||
impl FromEnvString for &'static str {
|
||||
type Err = ();
|
||||
|
||||
fn from_env_string(s: &EnvString) -> Result<Self, Self::Err> {
|
||||
Ok(Box::leak(s.0.clone().into_boxed_str()))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[doc(hidden)]
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub struct EnvString(String);
|
||||
|
|
|
@ -87,12 +87,14 @@
|
|||
|
||||
|
||||
// Rustc lints.
|
||||
#![deny(unused_imports)]
|
||||
//#![deny(unused_imports)]
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#[macro_use]
|
||||
extern crate failure;
|
||||
#[cfg(feature = "static")]
|
||||
extern crate lazy_static;
|
||||
|
||||
mod enverr;
|
||||
mod getenv;
|
||||
|
@ -108,7 +110,7 @@ pub mod prelude {
|
|||
|
||||
|
||||
#[cfg(feature = "macro")]
|
||||
#[allow(unused_imports)]
|
||||
//#[allow(unused_imports)]
|
||||
#[macro_use]
|
||||
mod r#macro;
|
||||
#[cfg(feature = "macro")]
|
||||
|
|
|
@ -301,6 +301,14 @@ macro_rules! __itconfig_parse_module {
|
|||
}
|
||||
|
||||
|
||||
#[macro_export]
|
||||
#[doc(hidden)]
|
||||
macro_rules! __itconfig_get_ty_or_default {
|
||||
() => { &'static str };
|
||||
($ty:ty) => { $ty };
|
||||
}
|
||||
|
||||
|
||||
#[macro_export]
|
||||
#[doc(hidden)]
|
||||
macro_rules! __itconfig_parse_variables {
|
||||
|
@ -329,6 +337,30 @@ macro_rules! __itconfig_parse_variables {
|
|||
}
|
||||
};
|
||||
|
||||
// Find static concatenated variable
|
||||
(
|
||||
tokens = [
|
||||
$(#$meta:tt)*
|
||||
static $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,
|
||||
is_static = true,
|
||||
},
|
||||
tokens = [$($rest)*],
|
||||
$($args)*
|
||||
}
|
||||
};
|
||||
|
||||
// Find concatenated variable
|
||||
(
|
||||
tokens = [
|
||||
|
@ -346,17 +378,18 @@ macro_rules! __itconfig_parse_variables {
|
|||
concat = [],
|
||||
name = $name,
|
||||
ty = String,
|
||||
is_static = false,
|
||||
},
|
||||
tokens = [$($rest)*],
|
||||
$($args)*
|
||||
}
|
||||
};
|
||||
|
||||
// Find variable
|
||||
// Find static variable
|
||||
(
|
||||
tokens = [
|
||||
$(#$meta:tt)*
|
||||
$name:ident : $ty:ty$( => $default:expr)?,
|
||||
static $name:ident $(: $ty:ty)? $(=> $default:expr)?,
|
||||
$($rest:tt)*
|
||||
],
|
||||
$($args:tt)*
|
||||
|
@ -368,7 +401,33 @@ macro_rules! __itconfig_parse_variables {
|
|||
unparsed_concat = [],
|
||||
concat = [],
|
||||
name = $name,
|
||||
ty = $ty,
|
||||
ty = __itconfig_get_ty_or_default!($($ty)?),
|
||||
is_static = true,
|
||||
$(default = $default,)?
|
||||
},
|
||||
tokens = [$($rest)*],
|
||||
$($args)*
|
||||
}
|
||||
};
|
||||
|
||||
// Find variable
|
||||
(
|
||||
tokens = [
|
||||
$(#$meta:tt)*
|
||||
$name:ident $(: $ty:ty)? $(=> $default:expr)?,
|
||||
$($rest:tt)*
|
||||
],
|
||||
$($args:tt)*
|
||||
) => {
|
||||
__itconfig_parse_variables! {
|
||||
current_variable = {
|
||||
unparsed_meta = [$(#$meta)*],
|
||||
meta = [],
|
||||
unparsed_concat = [],
|
||||
concat = [],
|
||||
name = $name,
|
||||
ty = __itconfig_get_ty_or_default!($($ty)?),
|
||||
is_static = false,
|
||||
$(default = $default,)?
|
||||
},
|
||||
tokens = [$($rest)*],
|
||||
|
@ -523,6 +582,9 @@ macro_rules! __itconfig_impl_namespace {
|
|||
meta = $var_meta:tt,
|
||||
concat = $var_concat:tt,
|
||||
name = $var_name:ident,
|
||||
$(env_name = $env_name:expr,)?
|
||||
ty = $ty:ty,
|
||||
is_static = $is_static:ident,
|
||||
$($variable:tt)*
|
||||
},)*],
|
||||
namespaces = [$({
|
||||
|
@ -543,6 +605,8 @@ macro_rules! __itconfig_impl_namespace {
|
|||
$(#$meta)*
|
||||
pub mod $mod_name {
|
||||
#![allow(non_snake_case)]
|
||||
#[cfg(feature = "static")]
|
||||
use lazy_static::lazy_static;
|
||||
|
||||
$(__itconfig_impl_namespace! {
|
||||
variables = $ns_variable,
|
||||
|
@ -567,6 +631,9 @@ macro_rules! __itconfig_impl_namespace {
|
|||
concat = $var_concat,
|
||||
name = $var_name,
|
||||
env_prefix = $env_prefix,
|
||||
$(env_name = $env_name,)?
|
||||
ty = $ty,
|
||||
is_static = $is_static,
|
||||
$($variable)*
|
||||
})*
|
||||
}
|
||||
|
@ -630,37 +697,74 @@ macro_rules! __itconfig_variable {
|
|||
|
||||
// Add method for env variable
|
||||
(
|
||||
meta = [$(#$meta:tt,)*],
|
||||
meta = $meta:tt,
|
||||
concat = $concat:tt,
|
||||
name = $name:ident,
|
||||
env_prefix = $env_prefix:expr,
|
||||
env_name = $env_name:expr,
|
||||
ty = $ty:ty,
|
||||
is_static = $is_static:ident,
|
||||
$(default = $default:expr,)?
|
||||
) => {
|
||||
$(#$meta)*
|
||||
pub fn $name() -> $ty {
|
||||
__itconfig_variable! {
|
||||
__itconfig_variable!(
|
||||
@wrap
|
||||
is_static = $is_static,
|
||||
meta = $meta,
|
||||
name = $name,
|
||||
ty = $ty,
|
||||
value = __itconfig_variable!(
|
||||
@inner
|
||||
concat = $concat,
|
||||
env_name = $env_name,
|
||||
$(default = $default,)?
|
||||
}
|
||||
}
|
||||
),
|
||||
);
|
||||
};
|
||||
|
||||
// Wrap static variables
|
||||
(
|
||||
@wrap
|
||||
is_static = true,
|
||||
meta = [$(#$meta:tt,)*],
|
||||
name = $name:ident,
|
||||
ty = $ty:ty,
|
||||
value = $value:expr,
|
||||
) => (
|
||||
$(#$meta)*
|
||||
pub fn $name() -> $ty {
|
||||
lazy_static! {
|
||||
static ref $name: $ty = $value;
|
||||
}
|
||||
|
||||
(*$name).clone()
|
||||
}
|
||||
);
|
||||
|
||||
// Wrap functions
|
||||
(
|
||||
@wrap
|
||||
is_static = false,
|
||||
meta = [$(#$meta:tt,)*],
|
||||
name = $name:ident,
|
||||
ty = $ty:ty,
|
||||
value = $value:expr,
|
||||
) => (
|
||||
$(#$meta)*
|
||||
pub fn $name() -> $ty { $value }
|
||||
);
|
||||
|
||||
// Concatenate function body
|
||||
(
|
||||
@inner
|
||||
concat = [$($concat:expr,)+],
|
||||
env_name = $env_name:expr,
|
||||
$($args:tt)*
|
||||
) => (
|
||||
) => ({
|
||||
let value_parts: Vec<String> = vec!($($concat),+);
|
||||
let value = value_parts.join("");
|
||||
std::env::set_var($env_name, value.as_str());
|
||||
value
|
||||
);
|
||||
});
|
||||
|
||||
// Env without default
|
||||
(
|
||||
|
|
Reference in a new issue