tera/renderer/
mod.rs

1mod square_brackets;
2#[cfg(test)]
3mod tests;
4
5mod call_stack;
6mod for_loop;
7mod macros;
8mod processor;
9mod stack_frame;
10
11use std::io::Write;
12
13use self::processor::Processor;
14use crate::errors::Result;
15use crate::template::Template;
16use crate::tera::Tera;
17use crate::utils::buffer_to_string;
18use crate::Context;
19
20/// Given a `Tera` and reference to `Template` and a `Context`, renders text
21#[derive(Debug)]
22pub struct Renderer<'a> {
23    /// Template to render
24    template: &'a Template,
25    /// Houses other templates, filters, global functions, etc
26    tera: &'a Tera,
27    /// Read-only context to be bound to template˝
28    context: &'a Context,
29    /// If set rendering should be escaped
30    should_escape: bool,
31}
32
33impl<'a> Renderer<'a> {
34    /// Create a new `Renderer`
35    #[inline]
36    pub fn new(template: &'a Template, tera: &'a Tera, context: &'a Context) -> Renderer<'a> {
37        let should_escape = tera.autoescape_suffixes.iter().any(|ext| {
38            // We prefer a `path` if set, otherwise use the `name`
39            if let Some(ref p) = template.path {
40                return p.ends_with(ext);
41            }
42            template.name.ends_with(ext)
43        });
44
45        Renderer { template, tera, context, should_escape }
46    }
47
48    /// Combines the context with the Template to generate the end result
49    pub fn render(&self) -> Result<String> {
50        let mut output = Vec::with_capacity(2000);
51        self.render_to(&mut output)?;
52        buffer_to_string(|| "converting rendered buffer to string".to_string(), output)
53    }
54
55    /// Combines the context with the Template to write the end result to output
56    pub fn render_to(&self, mut output: impl Write) -> Result<()> {
57        let mut processor =
58            Processor::new(self.template, self.tera, self.context, self.should_escape);
59
60        processor.render(&mut output)
61    }
62}