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#[derive(Debug)]
22pub struct Renderer<'a> {
23 template: &'a Template,
25 tera: &'a Tera,
27 context: &'a Context,
29 should_escape: bool,
31}
32
33impl<'a> Renderer<'a> {
34 #[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 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 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 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}