use std::env;
use crate::{
descriptor::{ConfigValueDescriptor, VarDescriptor},
error::ReadVarError,
layer::Layer,
};
pub struct TextVar {
descriptor: VarDescriptor,
}
impl TextVar {
pub fn from_var_name(var_name: &'static str) -> Self {
Self {
descriptor: VarDescriptor {
var_name,
description: None,
default_val_fmt: None,
},
}
}
pub fn description(mut self, description: &'static str) -> Self {
self.descriptor.description = Some(description);
self
}
pub fn default_fmt_val(mut self, default_fmt_val: &'static str) -> Self {
self.descriptor.default_val_fmt = Some(default_fmt_val);
self
}
}
impl ConfigValueDescriptor for TextVar {
#[inline(always)]
fn get_descriptor(&self) -> &VarDescriptor {
&self.descriptor
}
}
impl Layer for TextVar {
type Output = String;
type Error = ReadVarError;
fn try_get(&self) -> Result<Self::Output, Self::Error> {
env::var(self.descriptor.var_name).map_err(ReadVarError::Var)
}
}
#[cfg(test)]
mod tests {
use std::env::VarError;
use crate::{
error::ReadVarError,
prelude::*,
tests::{assert_matches, with_env},
};
#[test]
fn assert_var_non_present() {
const VAR_NAME: &str = "__TEST_VAR_NON_PRESENT";
let config = TextVar::from_var_name(VAR_NAME);
let res = with_env([], || config.try_get());
assert_matches!(res, Err(ReadVarError::Var(VarError::NotPresent)));
}
#[test]
fn assert_var_present() {
const VAR_NAME: &str = "__TEST_VAR_PRESENT";
let config = TextVar::from_var_name(VAR_NAME);
let res = with_env([(VAR_NAME, "hello there")], || config.try_get());
assert_matches!(res.as_deref(), Ok("hello there"));
}
}