use crate::{
util::cmp_keys, Configuration, ConfigurationBuilder, ConfigurationProvider,
ConfigurationSource, Value,
};
use std::borrow::Borrow;
use std::rc::Rc;
use tokens::ChangeToken;
pub struct ChainedConfigurationProvider {
configuration: Rc<dyn Configuration>,
}
impl ChainedConfigurationProvider {
pub fn new(configuration: Rc<dyn Configuration>) -> Self {
Self { configuration }
}
}
impl ConfigurationProvider for ChainedConfigurationProvider {
fn get(&self, key: &str) -> Option<Value> {
self.configuration.get(key)
}
fn reload_token(&self) -> Box<dyn ChangeToken> {
self.configuration.reload_token()
}
fn child_keys(&self, earlier_keys: &mut Vec<String>, parent_path: Option<&str>) {
if let Some(path) = parent_path {
earlier_keys.extend(
self.configuration
.section(path)
.children()
.iter()
.map(|c| c.key().to_owned()),
);
} else {
earlier_keys.extend(
self.configuration
.children()
.iter()
.map(|c| c.key().to_owned()),
);
}
earlier_keys.sort_by(|k1, k2| cmp_keys(k1, k2));
}
}
pub struct ChainedConfigurationSource {
configuration: Rc<dyn Configuration>,
}
impl ChainedConfigurationSource {
pub fn new(configuration: Box<dyn Configuration>) -> Self {
Self {
configuration: Rc::from(configuration),
}
}
pub fn configuration(&self) -> &dyn Configuration {
self.configuration.borrow()
}
}
impl ConfigurationSource for ChainedConfigurationSource {
fn build(&self, _builder: &dyn ConfigurationBuilder) -> Box<dyn ConfigurationProvider> {
Box::new(ChainedConfigurationProvider::new(
self.configuration.clone(),
))
}
}
impl From<Box<dyn Configuration>> for ChainedConfigurationSource {
fn from(value: Box<dyn Configuration>) -> Self {
Self::new(value)
}
}
impl From<Rc<dyn Configuration>> for ChainedConfigurationSource {
fn from(value: Rc<dyn Configuration>) -> Self {
Self {
configuration: value,
}
}
}
pub mod ext {
use super::*;
pub trait ChainedBuilderExtensions {
fn add_configuration(&mut self, configuration: Box<dyn Configuration>) -> &mut Self;
}
impl ChainedBuilderExtensions for dyn ConfigurationBuilder + '_ {
fn add_configuration(&mut self, configuration: Box<dyn Configuration>) -> &mut Self {
self.add(Box::new(ChainedConfigurationSource::new(configuration)));
self
}
}
impl<T: ConfigurationBuilder> ChainedBuilderExtensions for T {
fn add_configuration(&mut self, configuration: Box<dyn Configuration>) -> &mut Self {
self.add(Box::new(ChainedConfigurationSource::new(configuration)));
self
}
}
}