use std::io::{Error, ErrorKind, Result}; use std::collections::HashMap; use serde::de::DeserializeOwned; use log::info; pub const CFG_FILE_EXTENSION: &str = ".toml"; pub trait AppDef { fn app_def(&mut self, root_path: String ); // -> T; } pub trait FromFile { fn fix_root_path(&mut self, root_path: String ); // -> T; } pub fn load_from_file<'a, T: FromFile + DeserializeOwned>(file_cfg: &str, name: &str) -> Result { let item_cfg: T; let file_path: String; if file_cfg.contains(CFG_FILE_EXTENSION) { file_path = file_cfg.to_string(); } else { file_path = format!("{}{}",file_cfg.to_string(),CFG_FILE_EXTENSION); } let config_content: &'a str; match std::fs::read_to_string(&file_path) { Ok(cfgcontent) => config_content = Box::leak(cfgcontent.into_boxed_str()), Err(e) => return Err(Error::new( ErrorKind::InvalidInput, format!("Error read {}: {}",&file_path,e) )), }; match toml::from_str::(&config_content) { Ok(cfg) => item_cfg = cfg, Err(e) => return Err(Error::new( ErrorKind::InvalidInput, format!("Error loading config {}: {}",&file_path,e) )), }; info!("Loaded {} config from: {}", &name, &file_path); Ok(item_cfg) } pub trait DictFromFile { fn fix_root_path(&mut self, root_path: String ); // -> T; } pub fn load_dict_from_file<'a, T: DictFromFile + DeserializeOwned>(file_cfg: &str, name: &str) -> Result> { let item_cfg: HashMap; let file_path: String; if file_cfg.contains(CFG_FILE_EXTENSION) { file_path = file_cfg.to_string(); } else { file_path = format!("{}{}",file_cfg.to_string(),CFG_FILE_EXTENSION); } let config_content: &'a str; match std::fs::read_to_string(&file_path) { Ok(cfgcontent) => config_content = Box::leak(cfgcontent.into_boxed_str()), Err(e) => return Err(Error::new( ErrorKind::InvalidInput, format!("Error read {}: {}",&file_path,e) )), }; match toml::from_str::>(&config_content) { Ok(cfg) => { item_cfg = cfg }, Err(e) => { return Err(Error::new( ErrorKind::InvalidInput, format!("Error loading {} {}: {}",name,&file_path,e) )) }, }; info!("Loaded {} config from: {}", name, &file_path); Ok(item_cfg) }