lib_ruby_parser_nodes/
liquid_template.rs

1use crate::messages_data;
2use crate::nodes_data;
3
4pub struct LiquidTemplate {
5    path: String,
6    src: String,
7    filters: Vec<Box<dyn liquid_core::parser::ParseFilter>>,
8    globals: liquid::Object,
9}
10
11impl LiquidTemplate {
12    pub fn new<P: AsRef<str>>(path: P) -> Self {
13        let path = path.as_ref().to_string();
14        let src = std::fs::read_to_string(&path).unwrap_or_else(|e| {
15            eprintln!("Failed to read {}:\n{}", path, e);
16            std::process::exit(1);
17        });
18        Self {
19            path: path.clone(),
20            src,
21            filters: crate::filters::all(),
22            globals: liquid::object!({
23                "nodes": nodes_data::ALL_NODES,
24                "messages": messages_data::ALL_MESSAGES,
25                "template": path
26            }),
27        }
28    }
29
30    pub fn new_eval<S: AsRef<str>>(src: S) -> Self {
31        Self {
32            path: String::from("eval.liquid"),
33            src: src.as_ref().to_string(),
34            filters: crate::filters::all(),
35            globals: liquid::object!({
36                "nodes": nodes_data::ALL_NODES,
37                "messages": messages_data::ALL_MESSAGES,
38                "template": "eval.liquid"
39            }),
40        }
41    }
42
43    pub fn with_filter<F>(mut self, f: F) -> Self
44    where
45        F: Into<Box<dyn liquid_core::parser::ParseFilter>>,
46    {
47        self.filters.push(f.into());
48        self
49    }
50
51    pub fn with_global(mut self, name: &str, value: liquid_core::Value) -> Self {
52        self.globals.insert(name.to_owned().into(), value);
53        self
54    }
55
56    pub fn render(self) -> String {
57        let Self {
58            path,
59            src,
60            filters,
61            globals,
62        } = self;
63
64        println!("cargo:rerun-if-changed={}", path);
65
66        let mut builder = liquid::ParserBuilder::with_stdlib();
67        for filter in filters {
68            builder = builder.filter(filter);
69        }
70
71        let parser = builder.build().unwrap_or_else(|e| {
72            eprintln!("Failed to construct parser:\n{}", e);
73            std::process::exit(1);
74        });
75
76        let template = parser.parse(&src).unwrap_or_else(|e| {
77            eprintln!("Liquid template error ({}):\n{}", path, e);
78            std::process::exit(1);
79        });
80
81        template.render(&globals).unwrap_or_else(|e| {
82            eprintln!("Failed to render {} template:\n{}", path, e);
83            std::process::exit(1);
84        })
85    }
86}