op_config/providers/
optional.rs1use eyre::Result;
2use figment::{
3 value::{Dict, Map},
4 Error, Figment, Metadata, Profile, Provider,
5};
6
7use super::unwraps::UnwrapProfileProvider;
8
9#[derive(Debug)]
32pub struct OptionalStrictProfileProvider<P> {
33 provider: P,
34 profiles: Vec<Profile>,
35}
36
37impl<P> OptionalStrictProfileProvider<P> {
38 pub(crate) const PROFILE_PROFILE: Profile = Profile::const_new("profile");
39
40 #[allow(dead_code)]
42 pub fn new(provider: P, profiles: impl IntoIterator<Item = impl Into<Profile>>) -> Self {
43 Self {
44 provider,
45 profiles: profiles.into_iter().map(|profile| profile.into()).collect(),
46 }
47 }
48}
49
50impl<P: Provider> Provider for OptionalStrictProfileProvider<P> {
51 fn metadata(&self) -> Metadata {
52 self.provider.metadata()
53 }
54
55 fn data(&self) -> Result<Map<Profile, Dict>, Error> {
56 let mut figment = Figment::from(&self.provider);
57 for profile in &self.profiles {
58 figment = figment.merge(UnwrapProfileProvider::new(
59 &self.provider,
60 Self::PROFILE_PROFILE,
61 profile.clone(),
62 ));
63 }
64 figment.data().map_err(|err| {
65 if let Err(root_err) = self.provider.data() {
70 return root_err;
71 }
72 err
73 })
74 }
75
76 fn profile(&self) -> Option<Profile> {
77 self.profiles.last().cloned()
78 }
79}