1#[macro_use]
2extern crate lazy_static;
3#[cfg(feature = "monitor")]
4extern crate notify;
5
6use tera::Tera;
7use std::sync::RwLock;
8pub use tera::{
9 Context,
10 Value as TeraValue,
11 to_value,
12 Result as TeraResult
13};
14
15lazy_static! {
16 pub static ref TERA: RwLock<Tera> = RwLock::new(Tera::new("views/**/*").unwrap());
17}
18
19
20pub fn render(path: &str, context: Context) -> String {
21 #[cfg(feature = "monitor")]
22 monitor();
23
24 TERA.read()
25 .and_then(|tera| {
26 Ok(tera.render(path, &context).unwrap_or_else(|e| {
27 println!("rendering error: {:?}", e);
28 "rendering error".to_owned()
29 }))
30 })
31 .unwrap()
32}
33
34#[cfg(feature = "monitor")]
35fn monitor() {
36 use std::sync::{Once, ONCE_INIT};
37 use notify::{watcher, RecursiveMode, Watcher};
38 use std::sync::mpsc::channel;
39 use std::thread::spawn;
40 use std::time::Duration;
41
42 static START: Once = ONCE_INIT;
43
44 START.call_once(|| {
45 spawn(move || {
46 let (tx, rx) = channel();
47 let mut watcher = watcher(tx, Duration::from_secs(5)).unwrap();
48 watcher.watch("./views", RecursiveMode::Recursive).unwrap();
49
50 loop {
51 match rx.recv() {
52 Ok(_) => {
53 let _ = TERA.write().and_then(|mut tera| {
54 let _ = tera.full_reload();
55 Ok(())
56 });
57 println!("views change");
58 }
59 Err(e) => println!("watch error: {:?}", e),
60 }
61 }
62 });
63 });
64}
65
66#[cfg(test)]
67mod tests {
68 #[test]
69 fn it_works() {}
70}