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 proc_macro2::TokenStream as TokenStream2;
|
||||
use quote::{quote, ToTokens, TokenStreamExt};
|
||||
use syn::Path;
|
||||
use syn::Type;
|
||||
|
||||
fn vec_to_token_stream_2<T>(input: &Vec<T>) -> Vec<TokenStream2>
|
||||
where
|
||||
|
@ -145,6 +147,8 @@ impl ToTokens for Variable {
|
|||
} else if self.initial.is_some() {
|
||||
let initial = self.initial.as_ref().unwrap();
|
||||
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 {
|
||||
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())
|
||||
}
|
||||
}
|
||||
|
||||
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 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.
|
||||
///
|
||||
/// Panics
|
||||
|
@ -137,3 +165,89 @@ where
|
|||
fn make_panic<T>(e: EnvError) -> T {
|
||||
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