Skip to main content

config/
chained.rs

1use crate::{util::cmp_keys, Configuration, ConfigurationBuilder, ConfigurationProvider, ConfigurationSource, Value};
2use std::borrow::Borrow;
3use tokens::ChangeToken;
4
5#[cfg(not(feature = "async"))]
6type Rc<T> = std::rc::Rc<T>;
7
8#[cfg(feature = "async")]
9type Rc<T> = std::sync::Arc<T>;
10
11/// Represents a chained [`ConfigurationProvider`](crate::ConfigurationProvider).
12pub struct ChainedConfigurationProvider {
13    configuration: Rc<dyn Configuration>,
14}
15
16impl ChainedConfigurationProvider {
17    /// Initializes a new chained configuration provider.
18    ///
19    /// # Arguments
20    ///
21    /// * `configuration` - The [`Configuration`](crate::Configuration) to chain
22    pub fn new(configuration: Rc<dyn Configuration>) -> Self {
23        Self { configuration }
24    }
25}
26
27impl ConfigurationProvider for ChainedConfigurationProvider {
28    fn get(&self, key: &str) -> Option<Value> {
29        self.configuration.get(key)
30    }
31
32    fn reload_token(&self) -> Box<dyn ChangeToken> {
33        self.configuration.reload_token()
34    }
35
36    fn child_keys(&self, earlier_keys: &mut Vec<String>, parent_path: Option<&str>) {
37        if let Some(path) = parent_path {
38            earlier_keys.extend(
39                self.configuration
40                    .section(path)
41                    .children()
42                    .iter()
43                    .map(|c| c.key().to_owned()),
44            );
45        } else {
46            earlier_keys.extend(self.configuration.children().iter().map(|c| c.key().to_owned()));
47        }
48
49        earlier_keys.sort_by(|k1, k2| cmp_keys(k1, k2));
50    }
51}
52
53/// Represents a chained [`ConfigurationSource`](crate::ConfigurationSource).
54pub struct ChainedConfigurationSource {
55    configuration: Rc<dyn Configuration>,
56}
57
58impl ChainedConfigurationSource {
59    /// Initializes a new chained configuration sources.
60    ///
61    /// # Arguments
62    ///
63    /// * `configuration` - The [`Configuration`](crate::Configuration) to chain
64    pub fn new(configuration: Box<dyn Configuration>) -> Self {
65        Self {
66            configuration: Rc::from(configuration),
67        }
68    }
69
70    /// Gets the associated [`Configuration`](crate::Configuration).
71    pub fn configuration(&self) -> &dyn Configuration {
72        self.configuration.borrow()
73    }
74}
75
76impl ConfigurationSource for ChainedConfigurationSource {
77    fn build(&self, _builder: &dyn ConfigurationBuilder) -> Box<dyn ConfigurationProvider> {
78        Box::new(ChainedConfigurationProvider::new(self.configuration.clone()))
79    }
80}
81
82impl From<Box<dyn Configuration>> for ChainedConfigurationSource {
83    fn from(value: Box<dyn Configuration>) -> Self {
84        Self::new(value)
85    }
86}
87
88impl From<Rc<dyn Configuration>> for ChainedConfigurationSource {
89    fn from(value: Rc<dyn Configuration>) -> Self {
90        Self { configuration: value }
91    }
92}
93
94pub mod ext {
95
96    use super::*;
97
98    /// Defines extension methods for [`ConfigurationBuilder`](crate::ConfigurationBuilder).
99    pub trait ChainedBuilderExtensions {
100        /// Adds the existing configuration.
101        ///
102        /// # Arguments
103        ///
104        /// * `configuration` - The existing [`Configuration`](crate::Configuration) to add
105        fn add_configuration(&mut self, configuration: Box<dyn Configuration>) -> &mut Self;
106    }
107
108    impl ChainedBuilderExtensions for dyn ConfigurationBuilder + '_ {
109        fn add_configuration(&mut self, configuration: Box<dyn Configuration>) -> &mut Self {
110            self.add(Box::new(ChainedConfigurationSource::new(configuration)));
111            self
112        }
113    }
114
115    impl<T: ConfigurationBuilder> ChainedBuilderExtensions for T {
116        fn add_configuration(&mut self, configuration: Box<dyn Configuration>) -> &mut Self {
117            self.add(Box::new(ChainedConfigurationSource::new(configuration)));
118            self
119        }
120    }
121}