pub fn get_env_var(key: &str) -> anyhow::Result<String> {
match std::env::var(key) {
Ok(var) => Ok(var),
Err(_) => anyhow::bail!("environment variable '{key}' must be set"),
}
}
pub fn get_or_env_var(value: Option<String>, key: &str) -> anyhow::Result<String> {
match value {
Some(v) => Ok(v),
None => get_env_var(key),
}
}
#[must_use]
pub fn get_or_env_var_opt(value: Option<String>, key: &str) -> Option<String> {
value.or_else(|| std::env::var(key).ok())
}
#[must_use]
pub fn resolve_env_var_pair(
key: Option<String>,
secret: Option<String>,
key_var: &str,
secret_var: &str,
) -> Option<(String, String)> {
let key = get_or_env_var_opt(key, key_var)?;
let secret = get_or_env_var_opt(secret, secret_var)?;
Some((key, secret))
}
#[cfg(test)]
mod tests {
use rstest::*;
use super::*;
#[rstest]
fn test_get_env_var_success() {
if let Ok(path) = std::env::var("PATH") {
let result = get_env_var("PATH");
assert!(result.is_ok());
assert_eq!(result.unwrap(), path);
}
}
#[rstest]
fn test_get_env_var_not_set() {
let result = get_env_var("NONEXISTENT_ENV_VAR_THAT_SHOULD_NOT_EXIST_12345");
assert!(result.is_err());
assert!(result.unwrap_err().to_string().contains(
"environment variable 'NONEXISTENT_ENV_VAR_THAT_SHOULD_NOT_EXIST_12345' must be set"
));
}
#[rstest]
fn test_get_env_var_error_message_format() {
let var_name = "DEFINITELY_NONEXISTENT_VAR_123456789";
let result = get_env_var(var_name);
assert!(result.is_err());
let error_msg = result.unwrap_err().to_string();
assert!(error_msg.contains(var_name));
assert!(error_msg.contains("must be set"));
}
#[rstest]
fn test_get_or_env_var_with_some_value() {
let provided_value = Some("provided_value".to_string());
let result = get_or_env_var(provided_value, "PATH");
assert!(result.is_ok());
assert_eq!(result.unwrap(), "provided_value");
}
#[rstest]
fn test_get_or_env_var_with_none_and_env_var_set() {
if let Ok(path) = std::env::var("PATH") {
let result = get_or_env_var(None, "PATH");
assert!(result.is_ok());
assert_eq!(result.unwrap(), path);
}
}
#[rstest]
fn test_get_or_env_var_with_none_and_env_var_not_set() {
let result = get_or_env_var(None, "NONEXISTENT_ENV_VAR_THAT_SHOULD_NOT_EXIST_67890");
assert!(result.is_err());
assert!(result.unwrap_err().to_string().contains(
"environment variable 'NONEXISTENT_ENV_VAR_THAT_SHOULD_NOT_EXIST_67890' must be set"
));
}
#[rstest]
fn test_get_or_env_var_empty_string_value() {
let provided_value = Some(String::new());
let result = get_or_env_var(provided_value, "PATH");
assert!(result.is_ok());
assert_eq!(result.unwrap(), "");
}
#[rstest]
fn test_get_or_env_var_priority() {
if std::env::var("PATH").is_ok() {
let provided = Some("custom_value_takes_priority".to_string());
let result = get_or_env_var(provided, "PATH");
assert!(result.is_ok());
assert_eq!(result.unwrap(), "custom_value_takes_priority");
}
}
#[rstest]
fn test_get_or_env_var_opt_with_some_value() {
let provided_value = Some("provided_value".to_string());
let result = get_or_env_var_opt(provided_value, "PATH");
assert_eq!(result, Some("provided_value".to_string()));
}
#[rstest]
fn test_get_or_env_var_opt_with_none_and_env_var_set() {
if let Ok(path) = std::env::var("PATH") {
let result = get_or_env_var_opt(None, "PATH");
assert_eq!(result, Some(path));
}
}
#[rstest]
fn test_get_or_env_var_opt_with_none_and_env_var_not_set() {
let result = get_or_env_var_opt(None, "NONEXISTENT_ENV_VAR_OPT_12345");
assert_eq!(result, None);
}
#[rstest]
fn test_get_or_env_var_opt_priority() {
if std::env::var("PATH").is_ok() {
let provided = Some("custom_value".to_string());
let result = get_or_env_var_opt(provided, "PATH");
assert_eq!(result, Some("custom_value".to_string()));
}
}
#[rstest]
fn test_resolve_env_var_pair_both_provided() {
let result = resolve_env_var_pair(
Some("my_key".to_string()),
Some("my_secret".to_string()),
"NONEXISTENT_KEY_VAR",
"NONEXISTENT_SECRET_VAR",
);
assert_eq!(
result,
Some(("my_key".to_string(), "my_secret".to_string()))
);
}
#[rstest]
fn test_resolve_env_var_pair_key_missing_returns_none() {
let result = resolve_env_var_pair(
None,
Some("my_secret".to_string()),
"NONEXISTENT_PAIR_KEY_12345",
"NONEXISTENT_PAIR_SECRET_12345",
);
assert_eq!(result, None);
}
#[rstest]
fn test_resolve_env_var_pair_secret_missing_returns_none() {
let result = resolve_env_var_pair(
Some("my_key".to_string()),
None,
"NONEXISTENT_PAIR_KEY_12345",
"NONEXISTENT_PAIR_SECRET_12345",
);
assert_eq!(result, None);
}
#[rstest]
fn test_resolve_env_var_pair_both_missing_returns_none() {
let result = resolve_env_var_pair(
None,
None,
"NONEXISTENT_PAIR_KEY_12345",
"NONEXISTENT_PAIR_SECRET_12345",
);
assert_eq!(result, None);
}
}