feat: add possibility to get optional env
This commit is contained in:
parent
e479a1e40e
commit
d1982ad8af
4 changed files with 164 additions and 74 deletions
|
@ -1,6 +1,8 @@
|
||||||
use crate::ast::*;
|
use crate::ast::*;
|
||||||
use proc_macro2::TokenStream as TokenStream2;
|
use proc_macro2::TokenStream as TokenStream2;
|
||||||
use quote::{quote, ToTokens, TokenStreamExt};
|
use quote::{quote, ToTokens, TokenStreamExt};
|
||||||
|
use syn::Path;
|
||||||
|
use syn::Type;
|
||||||
|
|
||||||
fn vec_to_token_stream_2<T>(input: &Vec<T>) -> Vec<TokenStream2>
|
fn vec_to_token_stream_2<T>(input: &Vec<T>) -> Vec<TokenStream2>
|
||||||
where
|
where
|
||||||
|
@ -145,6 +147,8 @@ impl ToTokens for Variable {
|
||||||
} else if self.initial.is_some() {
|
} else if self.initial.is_some() {
|
||||||
let initial = self.initial.as_ref().unwrap();
|
let initial = self.initial.as_ref().unwrap();
|
||||||
quote!(::itconfig::get_env_or_set_default(#env_name, #initial))
|
quote!(::itconfig::get_env_or_set_default(#env_name, #initial))
|
||||||
|
} else if is_option_type(&self.ty) {
|
||||||
|
quote!(::itconfig::maybe_get_env(#env_name))
|
||||||
} else {
|
} else {
|
||||||
quote!(::itconfig::get_env_or_panic(#env_name))
|
quote!(::itconfig::get_env_or_panic(#env_name))
|
||||||
};
|
};
|
||||||
|
@ -170,3 +174,30 @@ impl ToTokens for Variable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn path_ident(path: &Path) -> String {
|
||||||
|
path.segments
|
||||||
|
.iter()
|
||||||
|
.into_iter()
|
||||||
|
.fold(String::with_capacity(250), |mut acc, v| {
|
||||||
|
acc.push_str(&v.ident.to_string());
|
||||||
|
acc.push('|');
|
||||||
|
acc
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_option_path_ident(path_ident: String) -> bool {
|
||||||
|
vec!["Option|", "std|option|Option|", "core|option|Option|"]
|
||||||
|
.into_iter()
|
||||||
|
.find(|s| &path_ident == *s)
|
||||||
|
.is_some()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_option_type(ty: &Type) -> bool {
|
||||||
|
match ty {
|
||||||
|
Type::Path(ty_path) => {
|
||||||
|
ty_path.qself.is_none() && is_option_path_ident(path_ident(&ty_path.path))
|
||||||
|
}
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -531,3 +531,22 @@ mod test_case_22 {
|
||||||
assert_eq!(config::STATIC_CONCAT_VARIABLE(), "static part".to_string())
|
assert_eq!(config::STATIC_CONCAT_VARIABLE(), "static part".to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mod test_case_23 {
|
||||||
|
use std::env;
|
||||||
|
|
||||||
|
itconfig::config! {
|
||||||
|
SOMETHING: Option<&'static str>,
|
||||||
|
NOTHING: Option<&'static str>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn optional_variables() {
|
||||||
|
config::init();
|
||||||
|
|
||||||
|
env::set_var("SOMETHING", "hello world");
|
||||||
|
|
||||||
|
assert_eq!(config::SOMETHING(), Some("hello world"));
|
||||||
|
assert_eq!(config::NOTHING(), None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,74 +0,0 @@
|
||||||
use itconfig::EnvError::*;
|
|
||||||
use itconfig::*;
|
|
||||||
use std::env;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[should_panic(expected = "Environment variable \"TEST_CASE_1\" is missing")]
|
|
||||||
fn get_missing_env() {
|
|
||||||
get_env_or_panic::<String>("TEST_CASE_1");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[should_panic(expected = "Failed to parse environment variable \"TEST_CASE_2\"")]
|
|
||||||
fn get_env_with_invalid_value() {
|
|
||||||
let env_name = "TEST_CASE_2";
|
|
||||||
env::set_var(&env_name, "30r");
|
|
||||||
get_env_or_panic::<u32>(env_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn get_result_of_missing_env() {
|
|
||||||
let env_name = String::from("TEST_CASE_3");
|
|
||||||
let env_val = get_env::<String>(&env_name);
|
|
||||||
assert_eq!(env_val, Err(MissingVariable(env_name)))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn get_result_of_env_with_invalid_value() {
|
|
||||||
let env_name = String::from("TEST_CASE_4");
|
|
||||||
env::set_var(&env_name, "30r");
|
|
||||||
let env_val = get_env::<u32>(&env_name);
|
|
||||||
assert_eq!(env_val, Err(FailedToParse(env_name)))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn get_result_of_env_successfully() {
|
|
||||||
env::set_var("TEST_CASE_5", "30");
|
|
||||||
let env_var = get_env("TEST_CASE_5");
|
|
||||||
assert_eq!(env_var, Ok(30));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn get_missing_env_with_default_value() {
|
|
||||||
let flag: bool = get_env_or_default("TEST_CASE_6", "true");
|
|
||||||
assert_eq!(flag, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[should_panic(expected = "Failed to parse environment variable \"TEST_CASE_7\"")]
|
|
||||||
fn get_invalid_env_with_default_value() {
|
|
||||||
env::set_var("TEST_CASE_7", "30r");
|
|
||||||
get_env_or_default::<u32, _>("TEST_CASE_7", 30);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[should_panic(expected = "Failed to parse environment variable \"TEST_CASE_8\"")]
|
|
||||||
fn get_env_with_invalid_default_value() {
|
|
||||||
get_env_or_default::<u32, _>("TEST_CASE_8", "30r");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn get_env_with_default_successfully() {
|
|
||||||
env::set_var("TEST_CASE_9", "10");
|
|
||||||
let env_val: u32 = get_env_or_default("TEST_CASE_9", 30);
|
|
||||||
assert_eq!(env_val, 10)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn get_missing_env_with_set_default_value() {
|
|
||||||
let flag: bool = get_env_or_set_default("TEST_CASE_10", "true");
|
|
||||||
assert_eq!(flag, true);
|
|
||||||
|
|
||||||
let env_var = env::var("TEST_CASE_10");
|
|
||||||
assert_eq!(env_var, Ok(String::from("true")))
|
|
||||||
}
|
|
|
@ -1,6 +1,34 @@
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use std::env;
|
use std::env;
|
||||||
|
|
||||||
|
/// Same as get_env but returns Option enum instead Result
|
||||||
|
///
|
||||||
|
/// Example
|
||||||
|
/// -------
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// # extern crate itconfig;
|
||||||
|
/// # use itconfig::maybe_get_env;
|
||||||
|
/// use std::env;
|
||||||
|
///
|
||||||
|
/// fn main () {
|
||||||
|
/// env::set_var("HOST", "https://example.com");
|
||||||
|
///
|
||||||
|
/// let host: Option<&'static str> = maybe_get_env("HOST");
|
||||||
|
/// let not_existence_host: Option<&'static str> = maybe_get_env("NOT_EXISTENCE_HOST");
|
||||||
|
///
|
||||||
|
/// assert_eq!(host, Some("https://example.com"));
|
||||||
|
/// assert_eq!(not_existence_host, None);
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
pub fn maybe_get_env<T>(env_name: &str) -> Option<T>
|
||||||
|
where
|
||||||
|
T: FromEnvString,
|
||||||
|
{
|
||||||
|
get_env(env_name).ok()
|
||||||
|
}
|
||||||
|
|
||||||
/// This function is similar as `get_env`, but it unwraps result with panic on error.
|
/// This function is similar as `get_env`, but it unwraps result with panic on error.
|
||||||
///
|
///
|
||||||
/// Panics
|
/// Panics
|
||||||
|
@ -137,3 +165,89 @@ where
|
||||||
fn make_panic<T>(e: EnvError) -> T {
|
fn make_panic<T>(e: EnvError) -> T {
|
||||||
panic!("{}", e)
|
panic!("{}", e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic(expected = "Environment variable \"TEST_CASE_1\" is missing")]
|
||||||
|
fn get_missing_env() {
|
||||||
|
get_env_or_panic::<String>("TEST_CASE_1");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic(expected = "Failed to parse environment variable \"TEST_CASE_2\"")]
|
||||||
|
fn get_env_with_invalid_value() {
|
||||||
|
let env_name = "TEST_CASE_2";
|
||||||
|
env::set_var(&env_name, "30r");
|
||||||
|
get_env_or_panic::<u32>(env_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn get_result_of_missing_env() {
|
||||||
|
let env_name = String::from("TEST_CASE_3");
|
||||||
|
let env_val = get_env::<String>(&env_name);
|
||||||
|
assert_eq!(env_val, Err(EnvError::MissingVariable(env_name)))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn get_result_of_env_with_invalid_value() {
|
||||||
|
let env_name = String::from("TEST_CASE_4");
|
||||||
|
env::set_var(&env_name, "30r");
|
||||||
|
let env_val = get_env::<u32>(&env_name);
|
||||||
|
assert_eq!(env_val, Err(EnvError::FailedToParse(env_name)))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn get_result_of_env_successfully() {
|
||||||
|
env::set_var("TEST_CASE_5", "30");
|
||||||
|
let env_var = get_env("TEST_CASE_5");
|
||||||
|
assert_eq!(env_var, Ok(30));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn get_missing_env_with_default_value() {
|
||||||
|
let flag: bool = get_env_or_default("TEST_CASE_6", "true");
|
||||||
|
assert_eq!(flag, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic(expected = "Failed to parse environment variable \"TEST_CASE_7\"")]
|
||||||
|
fn get_invalid_env_with_default_value() {
|
||||||
|
env::set_var("TEST_CASE_7", "30r");
|
||||||
|
get_env_or_default::<u32, _>("TEST_CASE_7", 30);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic(expected = "Failed to parse environment variable \"TEST_CASE_8\"")]
|
||||||
|
fn get_env_with_invalid_default_value() {
|
||||||
|
get_env_or_default::<u32, _>("TEST_CASE_8", "30r");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn get_env_with_default_successfully() {
|
||||||
|
env::set_var("TEST_CASE_9", "10");
|
||||||
|
let env_val: u32 = get_env_or_default("TEST_CASE_9", 30);
|
||||||
|
assert_eq!(env_val, 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn get_missing_env_with_set_default_value() {
|
||||||
|
let flag: bool = get_env_or_set_default("TEST_CASE_10", "true");
|
||||||
|
assert_eq!(flag, true);
|
||||||
|
|
||||||
|
let env_var = env::var("TEST_CASE_10");
|
||||||
|
assert_eq!(env_var, Ok(String::from("true")))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn get_optional_env() {
|
||||||
|
env::set_var("TEST_CASE_11", "something");
|
||||||
|
let something: Option<&'static str> = maybe_get_env("TEST_CASE_11");
|
||||||
|
assert_eq!(something, Some("something"));
|
||||||
|
|
||||||
|
let nothing: Option<&'static str> = maybe_get_env("TEST_CASE_11_NONE");
|
||||||
|
assert_eq!(nothing, None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Reference in a new issue