rocket_include_tera/debug/
reloadable.rs1use std::{
2 collections::HashMap,
3 ops::{Deref, DerefMut},
4 path::PathBuf,
5 time::SystemTime,
6};
7
8use tera::{Error as TeraError, Tera};
9
10#[derive(Debug)]
11pub struct ReloadableTera {
13 tera: Tera,
14 files: HashMap<&'static str, (PathBuf, Option<SystemTime>)>,
15}
16
17impl ReloadableTera {
18 #[inline]
20 pub fn new() -> ReloadableTera {
21 let tera = Tera::default();
22
23 ReloadableTera {
24 tera,
25 files: HashMap::new(),
26 }
27 }
28
29 #[inline]
31 pub fn register_template_file<P: Into<PathBuf>>(
32 &mut self,
33 name: &'static str,
34 file_path: P,
35 ) -> Result<(), TeraError> {
36 let file_path = file_path.into();
37
38 let metadata = file_path.metadata()?;
39
40 let mtime = metadata.modified().ok();
41
42 self.tera.add_template_file(&file_path, Some(name))?;
43
44 self.files.insert(name, (file_path, mtime));
45
46 Ok(())
47 }
48
49 #[inline]
53 pub fn unregister_template_file<S: AsRef<str>>(&mut self, name: S) -> Option<PathBuf> {
54 let name = name.as_ref();
55
56 self.files.remove(name).map(|(file_path, _)| file_path)
57 }
58
59 #[inline]
61 pub fn reload_if_needed(&mut self) -> Result<(), TeraError> {
62 for (name, (file_path, mtime)) in &mut self.files {
63 let metadata = file_path.metadata()?;
64
65 let (reload, new_mtime) = match mtime {
66 Some(mtime) => match metadata.modified() {
67 Ok(new_mtime) => (new_mtime > *mtime, Some(new_mtime)),
68 Err(_) => (true, None),
69 },
70 None => match metadata.modified() {
71 Ok(new_mtime) => (true, Some(new_mtime)),
72 Err(_) => (true, None),
73 },
74 };
75
76 if reload {
77 self.tera.add_template_file(&file_path, Some(name))?;
78
79 *mtime = new_mtime;
80 }
81 }
82
83 Ok(())
84 }
85}
86
87impl Default for ReloadableTera {
88 #[inline]
89 fn default() -> Self {
90 ReloadableTera::new()
91 }
92}
93
94impl Deref for ReloadableTera {
95 type Target = Tera;
96
97 #[inline]
98 fn deref(&self) -> &Self::Target {
99 &self.tera
100 }
101}
102
103impl DerefMut for ReloadableTera {
104 #[inline]
105 fn deref_mut(&mut self) -> &mut Self::Target {
106 &mut self.tera
107 }
108}