//! configuration struct and implementations use std::{ collections::HashMap, env::var, fs::{ create_dir, read_to_string, File }, io::Error, path::PathBuf, process::exit }; use tera::Context; use toml::{ map::Map, Value }; use crate::error; /// configuration struct pub struct Config { pub dir: String, inner: Map } impl Config { /// create a new Config using the file at '$HOME/.config/oink/oink.toml' pub fn new() -> Config { // get base config dir let home = var("HOME").unwrap(); let mut dir = PathBuf::from(&home); dir.push(".config/oink"); if !dir.exists() { println!("missing directory at {dir:?}, creating..."); let setup = setup_dirs(&dir); if setup.is_err() { error::setup_dirs(&dir); } println!("created configuration directory, exiting..."); exit(0); } // read toml file let mut toml_path = dir.clone(); toml_path.push("oink.toml"); let raw = read_to_string(toml_path).unwrap(); let toml_conf: Value = toml::from_str(&raw).unwrap(); let inner = toml_conf.as_table().unwrap(); // return struct Config { dir: dir.to_string_lossy().to_string(), inner: inner.to_owned() } } /// build tera context from "vars" and "colors" config sections pub fn context(&self) -> Context { let mut output = Context::new(); let vars = self.inner.get("vars"); if vars.is_some() { let vars = vars.unwrap().as_table().unwrap(); for (key, value) in vars.iter() { output.insert(key, value.as_str().unwrap()); } } let colors = self.inner.get("colors"); if colors.is_some() { let colors = colors.unwrap().as_table().unwrap(); let mut map = HashMap::<&str, &str>::new(); for (key, value) in colors.iter() { map.insert(key, value.as_str().unwrap()); } output.insert("colors", &map); } output } /// build array of targets from "target" array pub fn targets(&self) -> Vec> { let mut output = Vec::new(); let target_array: Option<&Value> = self.inner.get("target"); if target_array.is_some() { let target_array = target_array.unwrap().as_array().unwrap().to_owned(); for target in target_array { output.push(target.as_table().unwrap().to_owned()); } } output } } fn setup_dirs(path: &PathBuf) -> Result<(), Error> { // create main directory create_dir(path)?; // create template directory let mut templates = path.clone(); templates.push("templates/"); create_dir(templates)?; // create generated directory let mut generated = path.clone(); generated.push("generated/"); create_dir(generated)?; // create main toml let mut toml = path.clone(); toml.push("oink.toml"); File::create(toml)?; Ok(()) }