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 Postfixed<'a>(&'a str);
impl<'a> Postfixed<'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.ends_with(self.0) {
Some((k.trim_end_matches(self.0).to_owned(), v))
} else {
None
}
}))
}
pub fn postfix(&self) -> &str {
self.0
}
}
pub fn postfixed(postfix: &str) -> Postfixed<'_> {
Postfixed(postfix)
}
#[cfg(test)]
mod tests {
use super::*;
use serde::Deserialize;
use std::env;
#[derive(Debug, Deserialize, PartialEq, Eq)]
struct Test {
key: String,
}
#[test]
fn test_postfixed() {
env::set_var("KEY_APP", "value");
let postfixed = postfixed("_APP").from_env::<Test>().unwrap();
assert_eq!(
postfixed,
Test {
key: String::from("value")
}
)
}
}