use std::sync::Arc;
use serde::de::DeserializeOwned;
use thiserror::Error;
use crate::configuration_builder::ConfigurationBuilder;
use crate::configuration_provider::ConfigurationProvider;
use crate::value::{Value, ValueDeserializer};
use crate::value::deserializer::DeserializationError;
pub mod configuration_builder;
pub mod value;
pub mod configuration_provider;
#[derive(Clone, Debug)]
pub struct Configuration {
value: Arc<Value>,
}
impl Default for Configuration {
fn default() -> Self {
Configuration {
value: Arc::new(Value::None)
}
}
}
impl Configuration {
pub(crate) fn new(value: Value) -> Self {
Configuration {
value: Arc::new(value),
}
}
pub fn builder(provider: impl ConfigurationProvider) -> ConfigurationBuilder {
ConfigurationBuilder::new(provider)
}
pub fn get<T: DeserializeOwned>(&self, key: &str) -> Result<T, GetConfigurationError> {
let value = match self.value.get(key) {
Some(config) => config,
None => return Err(GetConfigurationError::MissingValue(key.to_string())),
};
T::deserialize(ValueDeserializer(value))
.map_err(|err| err.with_prefix(key.as_ref()))
.map_err(|error| GetConfigurationError::FailedToDeserialize {
error,
key: key.to_string(),
})
}
pub fn with_override(&self, key: &str, override_value: Value) -> Self {
let mut value = (*self.value).clone();
*value.get_mut_or_create(&key) = override_value;
return Configuration { value: Arc::new(value) };
}
}
#[derive(Error, Debug)]
pub enum GetConfigurationError {
#[error("Missing value [key = `{0}`]")]
MissingValue(String),
#[error("Failed to deserialize value [key = `{key}`]")]
FailedToDeserialize {
#[source]
error: DeserializationError,
key: String,
},
}