pub mod ffi;
use error::Result;
use error::Error;
use mustache;
use rustc_serialize::Encodable;
use std::convert::Into;
use std::fs;
use std::io::{Seek, SeekFrom};
use std::path::Path;
use tempfile::tempfile;
#[cfg_attr(feature = "remote-run", doc = "")]
#[cfg_attr(feature = "remote-run", doc = "To upload the rendered file to your host, you can pass it")]
#[cfg_attr(feature = "remote-run", doc = "straight into the `File` primitive:")]
#[cfg_attr(feature = "remote-run", doc = "")]
#[cfg_attr(feature = "remote-run", doc = "```no_run")]
#[cfg_attr(feature = "remote-run", doc = "# use inapi::{File, Host, MapBuilder, Template};")]
#[cfg_attr(feature = "remote-run", doc = "# let template = Template::new(\"/path/to/template\").unwrap();")]
#[cfg_attr(feature = "remote-run", doc = "# let data = MapBuilder::new().insert_str(\"key\", \"value\").build();")]
#[cfg_attr(feature = "remote-run", doc = "# let rendered_file = template.render_data(&data).unwrap();")]
#[cfg_attr(feature = "remote-run", doc = "let mut host = Host::connect(\"hosts/myhost.json\").unwrap();")]
#[cfg_attr(feature = "remote-run", doc = "")]
#[cfg_attr(feature = "remote-run", doc = "let file = File::new(&mut host, \"/path/to/remote/file\").unwrap();")]
#[cfg_attr(feature = "remote-run", doc = "file.upload_file(&mut host, rendered_file, None).unwrap();")]
#[cfg_attr(feature = "remote-run", doc = "```")]
pub struct Template {
inner: mustache::Template,
}
impl Template {
pub fn new<P: AsRef<Path>>(path: P) -> Result<Template> {
if !path.as_ref().exists() {
return Err(Error::Generic("Template path does not exist".into()));
}
Ok(Template {
inner: try!(mustache::compile_path(path.as_ref())),
})
}
pub fn render<T: Encodable>(&self, data: &T) -> Result<fs::File> {
let mut fh = try!(tempfile());
try!(self.inner.render(&mut fh, data));
try!(fh.seek(SeekFrom::Start(0)));
Ok(fh)
}
pub fn render_data(&self, data: &mustache::Data) -> Result<fs::File> {
let mut fh = try!(tempfile());
self.inner.render_data(&mut fh, data)?;
try!(fh.seek(SeekFrom::Start(0)));
Ok(fh)
}
}
#[cfg(test)]
mod tests {
use mustache::MapBuilder;
use std::fs;
use std::io::{Read, Write};
use super::*;
use tempdir::TempDir;
#[test]
fn test_new() {
let tempdir = TempDir::new("template_test_render").unwrap();
let template_path = format!("{}/template.mustache", tempdir.path().to_str().unwrap());
assert!(Template::new(&template_path).is_err());
fs::File::create(&template_path).unwrap();
Template::new(&template_path).unwrap();
assert!(Template::new(&template_path).is_ok());
}
#[test]
fn test_render() {
let tempdir = TempDir::new("template_test_render").unwrap();
let template_path = format!("{}/template.mustache", tempdir.path().to_str().unwrap());
let template_str = "Hello, {{name}}!".to_string();
let data = TestData {
name: "Jasper Beardly"
};
let mut fh = fs::File::create(&template_path).unwrap();
fh.write_all(template_str.as_bytes()).unwrap();
let template = Template::new(&template_path).unwrap();
let mut fh = template.render(&data).unwrap();
let mut content = String::new();
fh.read_to_string(&mut content).unwrap();
assert_eq!(content, "Hello, Jasper Beardly!");
}
#[test]
fn test_render_data_to_file() {
let tempdir = TempDir::new("template_test_render").unwrap();
let template_path = format!("{}/template.mustache", tempdir.path().to_str().unwrap());
let template_str = "Hello, {{name}}!".to_string();
let data = MapBuilder::new().insert_str("name", "Jasper Beardly").build();
let mut fh = fs::File::create(&template_path).unwrap();
fh.write_all(template_str.as_bytes()).unwrap();
let template = Template::new(&template_path).unwrap();
let mut fh = template.render_data(&data).unwrap();
let mut content = String::new();
fh.read_to_string(&mut content).unwrap();
assert_eq!(content, "Hello, Jasper Beardly!");
}
#[derive(RustcEncodable)]
struct TestData {
name: &'static str,
}
}