diff --git a/Cargo.toml b/Cargo.toml index 9fa5ff5..a62c3f6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "oink" -version = "0.1.1" +version = "0.2.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/src/config.rs b/src/config.rs index 902b8b9..f1a6e7b 100644 --- a/src/config.rs +++ b/src/config.rs @@ -15,9 +15,10 @@ use toml::{ Value }; -use crate::error; +use crate::{ error, util }; pub type Context = BTreeMap; +pub type Table = toml::map::Map; /// configuration struct pub struct Config { @@ -55,25 +56,38 @@ impl Config { } } - /// build tera context from "vars" and "colors" config sections - pub fn context(&self) -> Context { + /// build context from "vars" and "colors" config sections + pub fn context(&self, target: &Table) -> Context { let mut output = Context::new(); - let vars = self.inner.get("vars"); - if vars.is_some() { - let vars = vars.unwrap().as_table().unwrap(); + // pull global vars + if let Some(Value::Table(vars)) = self.inner.get("vars") { for (key, value) in vars.iter() { output.insert(key.to_owned(), value.as_str().into()); } } - let colors = self.inner.get("colors"); - if colors.is_some() { - let colors = colors.unwrap().as_table().unwrap(); - let mut map = Context::new(); - for (key, value) in colors.iter() { - map.insert(key.to_owned(), value.as_str().unwrap().into()); + + // pull target values + for (key, value) in target.iter() { + if key.to_uppercase() == *key { + output.insert(key.to_owned(), value.as_str().unwrap().into()); + } + } + + // pull palette + let palette_name: Option = + if let Some(Value::String(name)) = target.get("use_palette") { Some(name.clone()) } + else if let Some(Value::String(name)) = self.inner.get("use_palette") { Some(name.clone()) } + else { None }; + if let Some(Value::Array(array)) = self.inner.get("palette") { + let palette = util::matches(array.to_owned(), palette_name.unwrap_or("default".to_string())); + if let Some(Value::Table(palette)) = palette { + let colors = Context::new(); + for(key, value) in palette.iter() { + output.insert(key.to_owned(), value.as_str().unwrap().into()); + } + output.insert("palette".to_string(), colors.into()); } - output.insert("colors".to_owned(), map.into()); } output diff --git a/src/error.rs b/src/error.rs index 2446fe5..4025c7e 100644 --- a/src/error.rs +++ b/src/error.rs @@ -3,6 +3,11 @@ use std::{ process::exit }; +pub fn no_command() { + crate::help_text(); + exit(1); +} + pub fn no_targets() { println!("oink: configuration has no targets"); exit(2); diff --git a/src/main.rs b/src/main.rs index b7fba16..e9124d9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,10 +1,10 @@ -use std::process::exit; use pico_args::Arguments; mod config; mod error; mod operation; +mod util; use crate::config::Config; @@ -27,23 +27,18 @@ fn main() { match operation.as_deref() { Some("apply") - => { - operation::apply(&targets); - }, + => operation::apply(&targets), + Some("build") - => { - operation::build(&targets, template_dir, &config); - }, + => operation::build(&targets, template_dir, &config), + Some("full") => { operation::build(&targets, template_dir, &config); operation::apply(&targets); }, - _ - => { - help_text(); - exit(1); - } + + _ => error::no_command() } } diff --git a/src/operation.rs b/src/operation.rs index b4f1ddb..e267627 100644 --- a/src/operation.rs +++ b/src/operation.rs @@ -69,9 +69,9 @@ pub fn build(targets: &Vec>, template_dir: String, config: &C println!("running build:"); let engine = Engine::new(); - let context = config.context(); for target in targets { + let context = config.context(target); // get name property let i_name = target.get("name"); // handle empty names gracefully @@ -87,7 +87,9 @@ pub fn build(targets: &Vec>, template_dir: String, config: &C // compile println!(" {ITALIC}compiling{RESET}"); let mut path = PathBuf::from(&template_dir); - path.push(name); + if let Some(Value::String(base)) = target.get("base") { path.push(base); } + else { path.push(name); } + let content = read_to_string(path).unwrap(); let template = engine.compile(&content); if template.is_err() { diff --git a/src/util.rs b/src/util.rs new file mode 100644 index 0000000..e7d36cc --- /dev/null +++ b/src/util.rs @@ -0,0 +1,14 @@ + +use toml::{ value::Array, Value }; + +pub fn matches(array: Array, to_match: String) -> Option { + array.iter().filter(|value| { + if let Value::Table(table) = value { + if let Some(Value::String(name)) = table.get("name") { + return *name == to_match; + } + } + return false; + }).map(|value| value.to_owned()).nth(0) +} +