variant-config 0.1.4

variant config
Documentation
pub mod dsl;
mod resolver;
mod vc_config;

pub use anyhow;
pub use dsl::VariantValue;
pub use hashbrown;
use hashbrown::HashMap;
pub use log;
pub use resolver::*;
use serde::de::DeserializeOwned;
pub use serde_json;
pub use serde_yaml;
use std::sync::Arc;
pub use toml;
pub use vc_config::*;

pub struct VariantConfigStore {
    resolver: Arc<JsonConfigResolver>,
    pub global_variants: Arc<HashMap<String, VariantValue>>,
    pub config: Arc<VariantConfigStoreConfig>,
}

impl VariantConfigStore {
    pub fn new(
        json: serde_json::Value,
        global_variants: HashMap<String, VariantValue>,
    ) -> anyhow::Result<Self> {
        Self::new_with_config(json, global_variants, VariantConfigStoreConfig::default())
    }

    pub fn new_with_config(
        json: serde_json::Value,
        global_variants: HashMap<String, VariantValue>,
        config: VariantConfigStoreConfig,
    ) -> anyhow::Result<Self> {
        let resolver = JsonConfigResolver::new_with_custom_path(
            json,
            config.condition_path.clone(),
            config.value_path.clone(),
        )?;

        Ok(Self {
            resolver: Arc::new(resolver),
            global_variants: Arc::new(global_variants),
            config: Arc::new(config),
        })
    }

    pub fn new_from_yaml(
        yaml: &str,
        global_variants: HashMap<String, VariantValue>,
    ) -> anyhow::Result<Self> {
        Self::new_from_yaml_with_config(yaml, global_variants, VariantConfigStoreConfig::default())
    }

    pub fn new_from_yaml_with_config(
        yaml: &str,
        global_variants: HashMap<String, VariantValue>,
        config: VariantConfigStoreConfig,
    ) -> anyhow::Result<Self> {
        let json = serde_yaml::from_str(yaml)?;
        Self::new_with_config(json, global_variants, config)
    }

    pub fn new_from_toml(
        toml: &str,
        global_variants: HashMap<String, VariantValue>,
    ) -> anyhow::Result<Self> {
        Self::new_from_toml_with_config(toml, global_variants, VariantConfigStoreConfig::default())
    }

    pub fn new_from_toml_with_config(
        toml: &str,
        global_variants: HashMap<String, VariantValue>,
        config: VariantConfigStoreConfig,
    ) -> anyhow::Result<Self> {
        let json = toml::from_str(toml)?;
        Self::new_with_config(json, global_variants, config)
    }

    pub fn resolve(&self, variants: &HashMap<String, VariantValue>) -> serde_json::Value {
        if !variants.is_empty() {
            let mut merged = HashMap::with_capacity(self.global_variants.len() + variants.len());
            for (k, v) in variants {
                merged.insert(k.to_owned(), v.clone());
            }
            for (k, v) in &*self.global_variants {
                if !merged.contains_key(k) {
                    merged.insert(k.to_owned(), v.clone());
                }
            }
            self.resolver.resolve(&merged)
        } else {
            self.resolver.resolve(&self.global_variants)
        }
    }

    pub fn resolve_typed<T: DeserializeOwned>(
        &self,
        variants: &HashMap<String, VariantValue>,
    ) -> anyhow::Result<T> {
        let json = self.resolve(variants);
        let r = serde_json::from_value(json)?;
        Ok(r)
    }

    pub fn update_json(&mut self, json: serde_json::Value) -> anyhow::Result<()> {
        let resolver = JsonConfigResolver::new_with_custom_path(
            json,
            self.config.condition_path.clone(),
            self.config.value_path.clone(),
        )?;
        self.resolver = Arc::new(resolver);
        Ok(())
    }

    pub fn update_json_with_config(
        &mut self,
        json: serde_json::Value,
        config: &VariantConfigStoreConfig,
    ) -> anyhow::Result<()> {
        let resolver = JsonConfigResolver::new_with_custom_path(
            json,
            config.condition_path.clone(),
            config.value_path.clone(),
        )?;
        self.resolver = Arc::new(resolver);
        self.config = Arc::new(config.clone());
        Ok(())
    }

    pub fn update_global_variants(&mut self, global_variants: HashMap<String, VariantValue>) {
        self.global_variants = Arc::new(global_variants);
    }
}