arawasu 0.1.0

A command line utility for rendering templates
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 {
    /// Verbose mode (-v, -vv, -vvv, etc.)
    #[structopt(short = "v", long = "verbose", parse(from_occurrences))]
    verbose: u8,

    /// Quit on render errors
    #[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>,

    /// Directories where to search for partials/templates
    #[structopt(short = "p", long = "partials", parse(from_os_str))]
    partial_dirs: Vec<PathBuf>,

    /// Files to process
    #[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> {
    // setup
    let opt = Opt::from_args();
    let mut handlebars = Handlebars::new();

    // read the data
    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(())
}