use std::env;
use std::str::FromStr;
pub fn load_dotenv() {
let _ = dotenvy::dotenv();
}
pub fn get_env(key: &str) -> Result<String, ConfigError> {
env::var(key).map_err(|_| ConfigError::Missing(key.to_string()))
}
pub fn get_env_or(key: &str, default: &str) -> String {
env::var(key).unwrap_or_else(|_| default.to_string())
}
pub fn get_env_parsed<T: FromStr>(key: &str) -> Result<T, ConfigError> {
let value = get_env(key)?;
value.parse().map_err(|_| ConfigError::Invalid {
key: key.to_string(),
value,
})
}
pub fn get_env_parsed_or<T: FromStr>(key: &str, default: T) -> T {
env::var(key)
.ok()
.and_then(|v| v.parse().ok())
.unwrap_or(default)
}
#[derive(Debug)]
pub enum ConfigError {
Missing(String),
MissingMultiple(Vec<String>),
Invalid { key: String, value: String },
}
impl std::fmt::Display for ConfigError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ConfigError::Missing(key) => {
write!(f, "Missing required environment variable '{}'", key)
}
ConfigError::MissingMultiple(keys) => {
writeln!(f, "Missing required environment variables:")?;
for key in keys {
writeln!(f, " - {}", key)?;
}
Ok(())
}
ConfigError::Invalid { key, value } => {
write!(
f,
"Invalid value '{}' for environment variable '{}' (failed to parse as expected type)",
value, key
)
}
}
}
}
impl std::error::Error for ConfigError {}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_get_env_missing() {
let result = get_env("RAPINA_TEST_MISSING_VAR_12345");
assert!(result.is_err());
}
#[test]
fn test_get_env_or_default() {
let value = get_env_or("RAPINA_TEST_MISSING_VAR_12345", "default");
assert_eq!(value, "default");
}
#[test]
fn test_get_env_parsed_or_default() {
let value: u16 = get_env_parsed_or("RAPINA_TEST_MISSING_VAR_12345", 3000);
assert_eq!(value, 3000);
}
#[test]
fn test_config_error_display() {
let err = ConfigError::Missing("DATABASE_URL".to_string());
assert_eq!(
err.to_string(),
"Missing required environment variable 'DATABASE_URL'"
);
let err = ConfigError::Invalid {
key: "PORT".to_string(),
value: "abc".to_string(),
};
assert_eq!(
err.to_string(),
"Invalid value 'abc' for environment variable 'PORT' (failed to parse as expected type)"
);
}
}