use eyre::Result;
use figment::{
value::{Dict, Map},
Error, Figment, Metadata, Profile, Provider,
};
use super::unwraps::UnwrapProfileProvider;
#[derive(Debug)]
pub struct OptionalStrictProfileProvider<P> {
provider: P,
profiles: Vec<Profile>,
}
impl<P> OptionalStrictProfileProvider<P> {
pub(crate) const PROFILE_PROFILE: Profile = Profile::const_new("profile");
#[allow(dead_code)]
pub fn new(provider: P, profiles: impl IntoIterator<Item = impl Into<Profile>>) -> Self {
Self {
provider,
profiles: profiles.into_iter().map(|profile| profile.into()).collect(),
}
}
}
impl<P: Provider> Provider for OptionalStrictProfileProvider<P> {
fn metadata(&self) -> Metadata {
self.provider.metadata()
}
fn data(&self) -> Result<Map<Profile, Dict>, Error> {
let mut figment = Figment::from(&self.provider);
for profile in &self.profiles {
figment = figment.merge(UnwrapProfileProvider::new(
&self.provider,
Self::PROFILE_PROFILE,
profile.clone(),
));
}
figment.data().map_err(|err| {
if let Err(root_err) = self.provider.data() {
return root_err;
}
err
})
}
fn profile(&self) -> Option<Profile> {
self.profiles.last().cloned()
}
}