use deunicode::deunicode; use structopt::StructOpt; use toml::Value; //use std::collections::hash_map::DefaultHasher; use std::fs::{create_dir, read_to_string, write}; use std::path::PathBuf; #[derive(StructOpt, Debug)] /// structure representing command line arguments struct Opt { #[structopt(name = "FILE")] /// The input file. /// It contains all the settings related to substitution toml: PathBuf, #[structopt(short, long, default_value = "output")] /// Output directory. output: PathBuf, #[structopt(short, long)] /// Template to be processed. /// if a directory, then all the unspecified /// files will be copied to the output as well. template: PathBuf, } /// replaces {{ value }} with actual value fn replace(mut template: String, rules: &[(String, String)]) -> String { for (x, y) in rules { let l = format!("{{{{ {} }}}}", x); template = template.replace(&l, y) } template } /// collects table into a vector of String pairs fn collect_table(table: &Value) -> Vec<(String, String)> { table .as_table() .unwrap() .keys() .map(|x| (x.clone(), String::from(table[x].as_str().unwrap()))) .collect() } fn main() { // parse command line arguments let opt = Opt::from_args(); //println!("{:?}", opt); // parse toml let mut value = read_to_string(&opt.toml).unwrap().parse::().unwrap(); //println!("{:#?}", value); // create output directory // if it doesn't exist if !opt.output.exists() { create_dir(&opt.output).unwrap(); } // read template let input = read_to_string( &[opt.template, PathBuf::from("front.html")] .iter() .collect::(), ) .unwrap(); // create rules // hope to god the toml is correctly formatted // start with removing page rules let page = value .as_table_mut() .unwrap() .remove("page") .unwrap() .clone(); // collect global rules into a vec let global = collect_table(&value); // iterate over pages for (index, value) in page.as_array().unwrap().iter().enumerate() { // add global variables to table let mut table = collect_table(&value); table.extend(global.clone()); // TODO make this less of a pain let content = replace(input.clone(), table.as_slice()); // create the files let (code, day, time_start) = ( value["code"].as_str().unwrap(), value["day"].as_str().unwrap(), value["time_start"].as_str().unwrap(), ); // tweaks // day let mut day = String::from(day); day = deunicode(&day).to_uppercase(); // time_start let mut time_start = String::from(time_start); time_start = time_start.replace(":", ""); // code let code = String::from(code).replace(" ", "-"); let target = format!("PREZ_{}_{}_{}.html", code, &day[0..2], time_start); println!("writing {}", target); write( &[&opt.output, &PathBuf::from(target)] .iter() .collect::(), content, ) .unwrap(); } //println!("{:#?}", global); }