configuration is more flexible; targets can specify their base file, introduced palettes, and targets can specify & override variables

This commit is contained in:
Valerie Wolfe 2024-07-02 13:24:30 -04:00
parent 502e5a7615
commit 7fab543476
6 changed files with 58 additions and 28 deletions

View file

@ -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

View file

@ -15,9 +15,10 @@ use toml::{
Value
};
use crate::error;
use crate::{ error, util };
pub type Context = BTreeMap<String, ContextValue>;
pub type Table = toml::map::Map<String, Value>;
/// 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<String> =
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

View file

@ -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);

View file

@ -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()
}
}

View file

@ -69,9 +69,9 @@ pub fn build(targets: &Vec<Map<String, Value>>, 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<Map<String, Value>>, 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() {

14
src/util.rs Normal file
View file

@ -0,0 +1,14 @@
use toml::{ value::Array, Value };
pub fn matches(array: Array, to_match: String) -> Option<Value> {
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)
}