shiny_configuration/
lib.rs

1use std::sync::Arc;
2use serde::de::DeserializeOwned;
3use thiserror::Error;
4use crate::configuration_builder::ConfigurationBuilder;
5use crate::configuration_provider::ConfigurationProvider;
6use crate::value::{Value, ValueDeserializer};
7use crate::value::deserializer::DeserializationError;
8
9pub mod configuration_builder;
10pub mod value;
11pub mod configuration_provider;
12
13#[derive(Clone, Debug)]
14pub struct Configuration {
15    value: Arc<Value>,
16}
17
18impl Default for Configuration {
19    fn default() -> Self {
20        Configuration {
21            value: Arc::new(Value::None)
22        }
23    }
24}
25
26impl Configuration {
27    pub(crate) fn new(value: Value) -> Self {
28        Configuration {
29            value: Arc::new(value),
30        }
31    }
32
33    pub fn builder(provider: impl ConfigurationProvider) -> ConfigurationBuilder {
34        ConfigurationBuilder::new(provider)
35    }
36
37    pub fn get<T: DeserializeOwned>(&self, key: &str) -> Result<T, GetConfigurationError> {
38        let value = match self.value.get(key) {
39            Some(config) => config,
40            None => return Err(GetConfigurationError::MissingValue(key.to_string())),
41        };
42
43        T::deserialize(ValueDeserializer(value))
44            .map_err(|err| err.with_prefix(key.as_ref()))
45            .map_err(|error| GetConfigurationError::FailedToDeserialize {
46                error,
47                key: key.to_string(),
48            })
49    }
50
51    pub fn with_override(&self, key: &str, override_value: Value) -> Self {
52        let mut value = (*self.value).clone();
53
54        *value.get_mut_or_create(key) = override_value;
55
56        Configuration { value: Arc::new(value) }
57    }
58}
59
60#[derive(Error, Debug)]
61pub enum GetConfigurationError {
62    #[error("Missing value [key = `{0}`]")]
63    MissingValue(String),
64
65    #[error("Failed to deserialize value [key = `{key}`]")]
66    FailedToDeserialize {
67        #[source]
68        error: DeserializationError,
69        key: String,
70    },
71}