variant_config/
lib.rs

1pub mod dsl;
2mod resolver;
3mod vc_config;
4
5pub use anyhow;
6pub use dsl::VariantValue;
7pub use hashbrown;
8use hashbrown::HashMap;
9pub use log;
10pub use resolver::*;
11use serde::de::DeserializeOwned;
12pub use serde_json;
13pub use serde_yaml;
14use std::sync::Arc;
15pub use toml;
16pub use vc_config::*;
17
18pub struct VariantConfigStore {
19    resolver: Arc<JsonConfigResolver>,
20    pub global_variants: Arc<HashMap<String, VariantValue>>,
21    pub config: Arc<VariantConfigStoreConfig>,
22}
23
24impl VariantConfigStore {
25    pub fn new(
26        json: serde_json::Value,
27        global_variants: HashMap<String, VariantValue>,
28    ) -> anyhow::Result<Self> {
29        Self::new_with_config(json, global_variants, VariantConfigStoreConfig::default())
30    }
31
32    pub fn new_with_config(
33        json: serde_json::Value,
34        global_variants: HashMap<String, VariantValue>,
35        config: VariantConfigStoreConfig,
36    ) -> anyhow::Result<Self> {
37        let resolver = JsonConfigResolver::new_with_custom_path(
38            json,
39            config.condition_path.clone(),
40            config.value_path.clone(),
41        )?;
42
43        Ok(Self {
44            resolver: Arc::new(resolver),
45            global_variants: Arc::new(global_variants),
46            config: Arc::new(config),
47        })
48    }
49
50    pub fn new_from_yaml(
51        yaml: &str,
52        global_variants: HashMap<String, VariantValue>,
53    ) -> anyhow::Result<Self> {
54        Self::new_from_yaml_with_config(yaml, global_variants, VariantConfigStoreConfig::default())
55    }
56
57    pub fn new_from_yaml_with_config(
58        yaml: &str,
59        global_variants: HashMap<String, VariantValue>,
60        config: VariantConfigStoreConfig,
61    ) -> anyhow::Result<Self> {
62        let json = serde_yaml::from_str(yaml)?;
63        Self::new_with_config(json, global_variants, config)
64    }
65
66    pub fn new_from_toml(
67        toml: &str,
68        global_variants: HashMap<String, VariantValue>,
69    ) -> anyhow::Result<Self> {
70        Self::new_from_toml_with_config(toml, global_variants, VariantConfigStoreConfig::default())
71    }
72
73    pub fn new_from_toml_with_config(
74        toml: &str,
75        global_variants: HashMap<String, VariantValue>,
76        config: VariantConfigStoreConfig,
77    ) -> anyhow::Result<Self> {
78        let json = toml::from_str(toml)?;
79        Self::new_with_config(json, global_variants, config)
80    }
81
82    pub fn resolve(&self, variants: &HashMap<String, VariantValue>) -> serde_json::Value {
83        if !variants.is_empty() {
84            let mut merged = HashMap::with_capacity(self.global_variants.len() + variants.len());
85            for (k, v) in variants {
86                merged.insert(k.to_owned(), v.clone());
87            }
88            for (k, v) in &*self.global_variants {
89                if !merged.contains_key(k) {
90                    merged.insert(k.to_owned(), v.clone());
91                }
92            }
93            self.resolver.resolve(&merged)
94        } else {
95            self.resolver.resolve(&self.global_variants)
96        }
97    }
98
99    pub fn resolve_typed<T: DeserializeOwned>(
100        &self,
101        variants: &HashMap<String, VariantValue>,
102    ) -> anyhow::Result<T> {
103        let json = self.resolve(variants);
104        let r = serde_json::from_value(json)?;
105        Ok(r)
106    }
107
108    pub fn update_json(&mut self, json: serde_json::Value) -> anyhow::Result<()> {
109        let resolver = JsonConfigResolver::new_with_custom_path(
110            json,
111            self.config.condition_path.clone(),
112            self.config.value_path.clone(),
113        )?;
114        self.resolver = Arc::new(resolver);
115        Ok(())
116    }
117
118    pub fn update_json_with_config(
119        &mut self,
120        json: serde_json::Value,
121        config: &VariantConfigStoreConfig,
122    ) -> anyhow::Result<()> {
123        let resolver = JsonConfigResolver::new_with_custom_path(
124            json,
125            config.condition_path.clone(),
126            config.value_path.clone(),
127        )?;
128        self.resolver = Arc::new(resolver);
129        self.config = Arc::new(config.clone());
130        Ok(())
131    }
132
133    pub fn update_global_variants(&mut self, global_variants: HashMap<String, VariantValue>) {
134        self.global_variants = Arc::new(global_variants);
135    }
136}