Skip to main content

trillium_tera/
tera_handler.rs

1use std::{path::PathBuf, sync::Arc};
2use tera::{Context, Tera};
3use trillium::{Conn, Handler};
4
5/// A trillium handler for the Tera template engine
6#[derive(Clone, Debug)]
7pub struct TeraHandler(Arc<Tera>);
8
9impl From<PathBuf> for TeraHandler {
10    fn from(dir: PathBuf) -> Self {
11        dir.to_str().unwrap().into()
12    }
13}
14
15impl From<&str> for TeraHandler {
16    fn from(dir: &str) -> Self {
17        Tera::new(dir).unwrap().into()
18    }
19}
20
21impl From<&String> for TeraHandler {
22    fn from(dir: &String) -> Self {
23        Tera::new(dir).unwrap().into()
24    }
25}
26
27impl From<String> for TeraHandler {
28    fn from(dir: String) -> Self {
29        Tera::new(&dir).unwrap().into()
30    }
31}
32
33impl From<Tera> for TeraHandler {
34    fn from(tera: Tera) -> Self {
35        Self(Arc::new(tera))
36    }
37}
38
39impl From<&[&str]> for TeraHandler {
40    fn from(dir_parts: &[&str]) -> Self {
41        dir_parts.iter().collect::<PathBuf>().into()
42    }
43}
44
45impl TeraHandler {
46    /// Construct a new TeraHandler from either a `&str` or PathBuf that represents
47    /// a directory glob containing templates, or from a
48    /// [`tera::Tera`] instance
49    /// ```
50    /// # fn main() -> tera::Result<()> {
51    /// use std::{iter::FromIterator, path::PathBuf};
52    /// use trillium_tera::TeraHandler;
53    ///
54    /// let handler = TeraHandler::new(PathBuf::from_iter([".", "examples", "**", "*.html"]));
55    ///
56    /// // or
57    ///
58    /// let handler = TeraHandler::new("examples/*.html");
59    ///
60    /// // or
61    ///
62    /// let mut tera = trillium_tera::Tera::default();
63    /// tera.add_raw_template("hello.html", "hello {{name}}")?;
64    /// let handler = TeraHandler::new(tera);
65    /// # Ok(()) }
66    /// ```
67    pub fn new(tera: impl Into<Self>) -> Self {
68        tera.into()
69    }
70
71    pub(crate) fn tera(&self) -> &Tera {
72        &self.0
73    }
74}
75
76impl Handler for TeraHandler {
77    async fn run(&self, conn: Conn) -> Conn {
78        conn.with_state(self.clone()).with_state(Context::new())
79    }
80}