use crate::convert::maybe_invalid_unicode_vars_os;
use crate::{from_iter, Result};
use serde::de;
use std::{env, string::String};
#[derive(Debug)]
pub struct Prefixed<'a>(&'a str);
impl<'a> Prefixed<'a> {
pub fn from_env<T>(&self) -> Result<T>
where
T: de::DeserializeOwned,
{
self.from_iter(env::vars())
}
pub fn from_os_env<T>(&self) -> Result<T>
where
T: de::DeserializeOwned,
{
self.from_iter(maybe_invalid_unicode_vars_os()?)
}
pub fn from_iter<T, Iter>(&self, iter: Iter) -> Result<T>
where
T: de::DeserializeOwned,
Iter: IntoIterator<Item = (String, String)>,
{
from_iter(iter.into_iter().filter_map(|(k, v)| {
if k.starts_with(self.0) {
Some((k.trim_start_matches(self.0).to_owned(), v))
} else {
None
}
}))
}
pub fn prefix(&self) -> &str {
self.0
}
}
pub fn prefixed(prefix: &str) -> Prefixed<'_> {
Prefixed(prefix)
}
#[cfg(test)]
mod test_prefixed {
use serde::Deserialize;
use std::env;
use super::prefixed;
#[derive(Debug, Deserialize, PartialEq, Eq)]
struct Test {
key: String,
}
#[test]
fn test_prefixed() {
env::set_var("APP_KEY", "value");
let prefixed = prefixed("APP_").from_env::<Test>().unwrap();
assert_eq!(
prefixed,
Test {
key: String::from("value")
}
)
}
}