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]
51 pub fn unregister_template_file<S: AsRef<str>>(&mut self, name: S) -> Option<PathBuf> {
52 let name = name.as_ref();
53
54 self.files.remove(name).map(|(file_path, _)| {
55 file_path
57 })
58 }
59
60 #[inline]
62 pub fn reload_if_needed(&mut self) -> Result<(), TeraError> {
63 for (name, (file_path, mtime)) in &mut self.files {
64 let metadata = file_path.metadata()?;
65
66 let (reload, new_mtime) = match mtime {
67 Some(mtime) => match metadata.modified() {
68 Ok(new_mtime) => (new_mtime > *mtime, Some(new_mtime)),
69 Err(_) => (true, None),
70 },
71 None => match metadata.modified() {
72 Ok(new_mtime) => (true, Some(new_mtime)),
73 Err(_) => (true, None),
74 },
75 };
76
77 if reload {
78 self.tera.add_template_file(&file_path, Some(name))?;
79
80 *mtime = new_mtime;
81 }
82 }
83
84 Ok(())
85 }
86}
87
88impl Default for ReloadableTera {
89 #[inline]
90 fn default() -> Self {
91 ReloadableTera::new()
92 }
93}
94
95impl Deref for ReloadableTera {
96 type Target = Tera;
97
98 #[inline]
99 fn deref(&self) -> &Self::Target {
100 &self.tera
101 }
102}
103
104impl DerefMut for ReloadableTera {
105 #[inline]
106 fn deref_mut(&mut self) -> &mut Self::Target {
107 &mut self.tera
108 }
109}