use ferrin_spec::error::LoadApiKeyError;
use ferrin_spec::error::LoadSettingError;
use secrecy::SecretString;
#[must_use]
#[allow(
clippy::disallowed_methods,
reason = "the single audited environment lookup; everything else goes through this module"
)]
pub fn env_var(name: &str) -> Option<String> {
std::env::var(name).ok()
}
#[derive(Debug)]
pub struct ApiKeyConfig<'a> {
pub api_key: Option<SecretString>,
pub environment_variable: &'a str,
pub parameter_name: &'a str,
pub description: &'a str,
}
pub fn load_api_key(config: ApiKeyConfig<'_>) -> Result<SecretString, LoadApiKeyError> {
if let Some(key) = config.api_key {
return Ok(key);
}
match env_var(config.environment_variable) {
Some(value) => Ok(SecretString::from(value)),
None => Err(LoadApiKeyError::new(format!(
"{} API key is missing. Pass it using the '{}' parameter or the {} environment variable.",
config.description, config.parameter_name, config.environment_variable
))),
}
}
#[derive(Debug)]
pub struct SettingConfig<'a> {
pub value: Option<String>,
pub environment_variable: &'a str,
pub setting_name: &'a str,
pub description: &'a str,
}
pub fn load_setting(config: SettingConfig<'_>) -> Result<String, LoadSettingError> {
if let Some(value) = config.value {
return Ok(value);
}
env_var(config.environment_variable).ok_or_else(|| {
LoadSettingError::new(format!(
"{} setting is missing. Pass it using the '{}' parameter or the {} environment variable.",
config.description, config.setting_name, config.environment_variable
))
})
}
#[must_use]
pub fn load_optional_setting(value: Option<String>, environment_variable: &str) -> Option<String> {
value.or_else(|| env_var(environment_variable))
}