rocket_include_tera/debug/
manager.rs1use std::sync::{Mutex, PoisonError};
2
3use serde::Serialize;
4use tera::Context;
5
6use super::{ReloadableTera, TeraResponse};
7use crate::{functions::compute_data_etag, EtagIfNoneMatch};
8
9#[derive(Educe)]
11#[educe(Debug)]
12pub struct TeraContextManager {
13 pub tera: Mutex<ReloadableTera>,
14}
15
16impl TeraContextManager {
17 #[inline]
18 pub(crate) fn new(tera: Mutex<ReloadableTera>, _cache_capacity: usize) -> TeraContextManager {
19 TeraContextManager {
20 tera,
21 }
22 }
23
24 #[inline]
26 pub fn build<S: AsRef<str>, V: Serialize>(
27 &self,
28 etag_if_none_match: &EtagIfNoneMatch<'_>,
29 minify: bool,
30 name: S,
31 context: V,
32 ) -> TeraResponse {
33 self.tera
34 .lock()
35 .unwrap_or_else(PoisonError::into_inner)
36 .render(name.as_ref(), &Context::from_serialize(context).unwrap())
37 .map(|html| {
38 let etag = compute_data_etag(html.as_bytes());
39
40 if etag_if_none_match.weak_eq(&etag) {
41 TeraResponse::not_modified()
42 } else {
43 let html = if minify { html_minifier::minify(html).unwrap() } else { html };
44
45 TeraResponse::build_not_cache(html, &etag)
46 }
47 })
48 .unwrap()
49 }
50
51 #[inline]
53 pub fn render<S: AsRef<str>, V: Serialize>(&self, name: S, context: V) -> String {
54 self.tera
55 .lock()
56 .unwrap_or_else(PoisonError::into_inner)
57 .render(name.as_ref(), &Context::from_serialize(context).unwrap())
58 .unwrap()
59 }
60}