askama_plus_html5ever/
lib.rs

1// Copyright 2021 René Kijewski and the html5ever Project Developers.
2// See the COPYRIGHT file at the top-level directory of this distribution.
3//
4// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
5// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
7// option. This file may not be copied, modified, or distributed
8// except according to those terms.
9
10#![forbid(unsafe_code)]
11#![deny(missing_docs)]
12
13//! A simple library to parse [askama] templates, and tidy them up using
14//! [html5ever](https://doc.servo.org/html5ever/index.html).
15
16use std::{fmt, io};
17
18use askama::Template;
19
20struct DisplayAdaptor<'a, T: Template>(&'a T);
21
22impl<T: Template> fmt::Display for DisplayAdaptor<'_, T> {
23    #[inline]
24    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
25        self.0.render_into(f).map_err(|_| fmt::Error)
26    }
27}
28
29/// Render a template into a writer, e.g. a [`Vec<u8>`].
30///
31/// This is an oppinionated default implementation that disables
32/// [html5ever](https://doc.servo.org/html5ever/index.html)'s script rendering.
33#[inline]
34pub fn render(tmpl: &impl Template, dest: impl io::Write) -> Result<(), io::Error> {
35    html5ever_arena_dom::render(&DisplayAdaptor(tmpl), dest)
36}
37
38#[cfg(test)]
39mod tests {
40    use askama::Template;
41
42    #[test]
43    fn test_render_simple_invocation() {
44        #[derive(Template)]
45        #[template(ext = "html", source = "<EM>Test&{{index}}>!")]
46        struct TestTemplate {
47            index: u32,
48        }
49
50        let mut data = Vec::default();
51        super::render(&TestTemplate { index: 1 }, &mut data).expect("Rendered ok");
52        let data = std::str::from_utf8(&data).expect("Valid UTF-8");
53
54        assert_eq!(
55            data,
56            "<html><head></head><body><em>Test&amp;1&gt;!</em></body></html>"
57        );
58    }
59}