sapper_tmpl/
lib.rs

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}