feat: added support for lists

This commit is contained in:
darwincereska
2026-06-08 05:39:49 -04:00
parent 849eb9d62a
commit 5743c0b490
6 changed files with 60 additions and 14 deletions
+3 -3
View File
@@ -12,9 +12,9 @@ impl EnvError {
/// Creates a new `EnvError::Invalid` with the given key, value, and message.
pub fn invalid<K, V, M>(key: K, value: V, message: M) -> Self
where
K: Into<String>,
V: Into<String>,
M: Into<String>,
K: Into<String>, // The key of the environment variable that was invalid.
V: Into<String>, // The value of the environment variable that was invalid.
M: Into<String>, // A message describing why the value was invalid.
{
Self::Invalid {
key: key.into(),
+10
View File
@@ -28,6 +28,16 @@ impl<T: Number> FromEnv for T {
}
}
/// Adds support for loading lists of values from environment variables.
impl<T: FromEnv> FromEnv for Vec<T> {
fn from_env(value: &str) -> Result<Self, EnvError> {
match parser::parse_list(value) {
Ok(value) => Ok(value),
Err(e) => Err(e)
}
}
}
/// Adds support for loading strings from environment variables.
impl FromEnv for String {
fn from_env(value: &str) -> Result<String, EnvError> {
+30 -9
View File
@@ -1,5 +1,6 @@
use std::fmt::Display;
use std::any::type_name;
use crate::FromEnv;
use crate::error::EnvError;
use std::str::FromStr;
@@ -21,18 +22,24 @@ impl Number for usize {}
impl Number for f32 {}
impl Number for f64 {}
/// Normalizes a string by trimming whitespace and converting to lowercase.
fn normalize(input: &str) -> String {
input.trim().to_lowercase().to_string()
}
/// Parses a string as a boolean value.
pub fn parse_bool(value: &str) -> Result<bool, EnvError> {
if value.to_lowercase() == "t" { return Ok(true) }
if value.to_lowercase() == "f" { return Ok(false) }
if value == "1" { return Ok(true) }
if value == "0" { return Ok(false) }
if value == "yes" { return Ok(true) }
if value == "no" { return Ok(false) }
let normalized = normalize(value);
if normalized == "t" { return Ok(true) }
if normalized == "f" { return Ok(false) }
if normalized == "1" { return Ok(true) }
if normalized == "0" { return Ok(false) }
if normalized == "yes" { return Ok(true) }
if normalized == "no" { return Ok(false) }
match value.parse::<bool>() {
Ok(value) => Ok(value),
Err(e) => Err(EnvError::invalid("bool", value, &e.to_string()))
match normalized.parse::<bool>() {
Ok(normalized) => Ok(normalized),
Err(e) => Err(EnvError::invalid("bool", normalized, &e.to_string()))
}
}
@@ -43,3 +50,17 @@ pub fn parse_number<T: Number>(value: &str) -> Result<T, EnvError> {
Err(e) => Err(EnvError::invalid(type_name::<T>(), value, &e.to_string()))
}
}
/// Parses a comma-separated list of values of the specified type.
pub fn parse_list<T: FromEnv>(value: &str) -> Result<Vec<T>, EnvError> {
let items = value.split(',').map(|item| item.trim());
let mut result = Vec::new();
for item in items {
match T::from_env(item) {
Ok(value) => result.push(value),
Err(e) => return Err(e)
}
}
Ok(result)
}