Skip to main content

config/
builder.rs

1use crate::{context, Configuration, Provider, Result, Settings};
2
3/// Represents a [configuration](crate::Configuration) builder.
4#[derive(Default)]
5pub struct Builder(Vec<Box<dyn Provider>>);
6
7impl Builder {
8    /// Gets the [configuration providers](Provider).
9    #[inline]
10    pub fn providers(&self) -> impl Iterator<Item = &dyn Provider> {
11        self.0.iter().map(AsRef::as_ref)
12    }
13
14    /// Adds a new configuration provider.
15    ///
16    /// # Arguments
17    ///
18    /// * `provider` - The [configuration provider](Provider) to add
19    #[inline]
20    pub fn add(&mut self, provider: impl Provider + 'static) {
21        self.0.push(Box::new(provider))
22    }
23
24    /// Builds a [configuration](Configuration) from the registered [configuration providers](Provider).
25    pub fn build(&self) -> Result<Configuration> {
26        let mut settings = Settings::new();
27        let mut tokens = Vec::with_capacity(self.0.len());
28        let scope = context::enter(self.0.iter().map(|p| p.name().to_owned()).collect());
29
30        for provider in &self.0 {
31            provider.load(&mut settings)?;
32            tokens.push(provider.reload_token());
33            context::next();
34        }
35
36        settings.shrink_to_fit();
37
38        Ok(Configuration::new(settings, tokens, scope.into()))
39    }
40}
41
42impl TryFrom<Builder> for Configuration {
43    type Error = crate::Error;
44
45    #[inline]
46    fn try_from(builder: Builder) -> Result<Self> {
47        builder.build()
48    }
49}