liquid_lib/stdlib/blocks/
raw_block.rs

1use std::io::Write;
2
3use liquid_core::error::ResultLiquidReplaceExt;
4use liquid_core::Language;
5use liquid_core::Renderable;
6use liquid_core::Result;
7use liquid_core::Runtime;
8use liquid_core::{BlockReflection, ParseBlock, TagBlock, TagTokenIter};
9
10#[derive(Copy, Clone, Debug, Default)]
11pub struct RawBlock;
12
13impl RawBlock {
14    pub fn new() -> Self {
15        Self
16    }
17}
18
19impl BlockReflection for RawBlock {
20    fn start_tag(&self) -> &str {
21        "raw"
22    }
23
24    fn end_tag(&self) -> &str {
25        "endraw"
26    }
27
28    fn description(&self) -> &str {
29        ""
30    }
31}
32
33impl ParseBlock for RawBlock {
34    fn parse(
35        &self,
36        mut arguments: TagTokenIter<'_>,
37        mut tokens: TagBlock<'_, '_>,
38        _options: &Language,
39    ) -> Result<Box<dyn Renderable>> {
40        // no arguments should be supplied, trying to supply them is an error
41        arguments.expect_nothing()?;
42
43        let content = tokens.escape_liquid(false)?.to_owned();
44
45        tokens.assert_empty();
46        Ok(Box::new(RawT { content }))
47    }
48
49    fn reflection(&self) -> &dyn BlockReflection {
50        self
51    }
52}
53
54#[derive(Clone, Debug)]
55struct RawT {
56    content: String,
57}
58
59impl Renderable for RawT {
60    fn render_to(&self, writer: &mut dyn Write, _runtime: &dyn Runtime) -> Result<()> {
61        write!(writer, "{}", self.content).replace("Failed to render")?;
62        Ok(())
63    }
64}
65
66#[cfg(test)]
67mod test {
68    use super::*;
69
70    use liquid_core::parser;
71    use liquid_core::runtime;
72    use liquid_core::runtime::RuntimeBuilder;
73
74    fn options() -> Language {
75        let mut options = Language::default();
76        options.blocks.register("raw".to_owned(), RawBlock.into());
77        options
78    }
79
80    fn unit_parse(text: &str) -> String {
81        let options = options();
82        let template = parser::parse(text, &options)
83            .map(runtime::Template::new)
84            .unwrap();
85
86        let runtime = RuntimeBuilder::new().build();
87
88        template.render(&runtime).unwrap()
89    }
90
91    #[test]
92    fn raw_text() {
93        let output = unit_parse("{%raw%}This is a test{%endraw%}");
94        assert_eq!(output, "This is a test");
95    }
96
97    #[test]
98    fn raw_escaped() {
99        let output = unit_parse("{%raw%}{%if%}{%endraw%}");
100        assert_eq!(output, "{%if%}");
101    }
102
103    #[test]
104    fn raw_mixed() {
105        let output = unit_parse("{%raw%}hello{%if%}world{%endraw%}");
106        assert_eq!(output, "hello{%if%}world");
107    }
108}