use serde::Deserialize;
use std::error::Error;
use std::path::Path;
use yaml_merge_keys::*;
use std::fs::{self};
use log::*;
use crate::{get_yaml_filename, get_env_vars};
pub fn read_yaml_from_string<T:for<'de> Deserialize<'de> >(str: &str) -> Result<T, Box<dyn Error>> {
use yaml_merge_keys::serde_yaml::Value;
let sy:Value = serde_yaml::from_str(str)?;
let v: Result<Value, serde_yaml::Error> = serde_yaml::to_value(sy);
let fix: Result<Value, MergeKeyError> = merge_keys_serde(v?);
Ok(serde_yaml::from_value(fix?)?)
}
pub fn read_yaml_from_file<T:for<'de> Deserialize<'de>, P: AsRef<Path>>(path: P) -> Result<T, Box<dyn Error>> {
let sfile:String = fs::read_to_string(path)?.parse()?;
read_yaml_from_string(&sfile)
}
pub trait CFGResolver {
fn get_from_argument(&self) -> Option<&str>;
}
pub struct DefaultResolver {}
impl CFGResolver for DefaultResolver {
fn get_from_argument(&self) -> Option<&str> { None }
}
pub fn get_config_file_name(resolver:&impl CFGResolver) -> String {
let config = match resolver.get_from_argument() {
Some(cfg)=>cfg.to_string(),
None=>{
let (_, conf_path, conf_dir, conf_file)=get_env_vars();
use std::env::*;
match var(&conf_path) {
Ok(cfg)=>cfg,
Err(_)=>{
let dir = match var(&conf_dir) {
Ok(d) => d,
Err(_)=>".".to_string()
};
let file = match var(&conf_file) {
Ok(f)=>f,
Err(_)=>get_yaml_filename()
};
format!("{}/{}", dir, file)
}
}
}
};
debug!("Using config file '{config}'");
config
}