use std::fs::File;
use std::io::{stdin, stdout};
use std::path::PathBuf;
use derive_more::From;
use handlebars::Handlebars;
use serde_json::json;
use structopt::StructOpt;
#[derive(StructOpt, Debug)]
#[structopt(name = "basic")]
struct Opt {
#[structopt(short = "v", long = "verbose", parse(from_occurrences))]
verbose: u8,
#[structopt(short = "s", long = "strict")]
strict: bool,
#[structopt(short = "o", long = "output", parse(from_os_str))]
output: Option<PathBuf>,
#[structopt(short = "d", long = "data", parse(from_os_str))]
data: Option<PathBuf>,
#[structopt(short = "p", long = "partials", parse(from_os_str))]
partial_dirs: Vec<PathBuf>,
#[structopt(short = "i", long = "input", parse(from_os_str))]
files: Vec<PathBuf>,
}
#[derive(Debug, From)]
enum Error {
TemplateFile(handlebars::TemplateFileError),
TemplateRender(handlebars::TemplateRenderError),
IO(std::io::Error),
Json(serde_json::Error),
}
fn main() -> Result<(), Error> {
let opt = Opt::from_args();
let mut handlebars = Handlebars::new();
let data = if let Some(path) = opt.data {
let mut file = File::open(path)?;
serde_json::from_reader(&mut file)?
} else {
json!({})
};
handlebars.set_strict_mode(opt.strict);
for dir in opt.partial_dirs.iter() {
handlebars.register_templates_directory(".hbs", dir)?;
}
let mut out = stdout();
if opt.files.is_empty() {
handlebars.render_template_source_to_write(&mut stdin(), &data, &mut out)?;
} else {
for file_name in opt.files.iter() {
let mut file = File::open(file_name)?;
handlebars.render_template_source_to_write(&mut file, &data, &mut out)?;
}
}
Ok(())
}