use std::collections::HashMap;
use minijinja::Environment;
use crate::{types::config_param::ConfigParam, yaml::yaml_string_to_configs};
pub struct ConfigBuilder<'a> {
jinja_env: Environment<'a>
}
impl<'a> ConfigBuilder<'a> {
pub fn new() -> Self {
let jinja_env = Environment::new();
Self {
jinja_env,
}
}
pub fn build_from_files(&self, paths: &String, overrides: &Option<ConfigParam>, ctx: &Option<ConfigParam>) -> Result<ConfigParam, String> {
let paths: Vec<String> = paths.split(":").map(|p| String::from(p)).collect();
let ctx = match ctx {
Some(c) => c,
None => &ConfigParam::HashMap(HashMap::new()),
};
let mut result: ConfigParam = ConfigParam::HashMap(HashMap::new());
for path in &paths {
let contents = match std::fs::read_to_string(path) {
Ok(c) => c,
Err(e) => return Err(format!("Failed to read the configuration file file '{}': {}", &path, e)),
};
let yaml_contents = match self.jinja_env.render_str(contents.as_str(), ctx) {
Ok(r) => r,
Err(e) => return Err(format!("Failed to render the configuration file '{}': {}", &path, e)),
};
for config_param_iter in yaml_string_to_configs(&yaml_contents)? {
result = ConfigParam::merge(&result, &config_param_iter)?;
}
}
if let Some(o) = overrides {
result = ConfigParam::merge(&result, o)?;
}
if let ConfigParam::HashMap(_) = result {
Ok(result)
} else {
Err(format!("The configuration is resolved into incorrect type: {}", result.type_to_str()))
}
}
}