gchemol_readwrite/template/
tera.rs

1// imports
2
3// [[file:~/Workspace/Programming/gchemol-rs/gchemol-readwrite/gchemol-readwrite.note::*imports][imports:1]]
4use super::*;
5use gchemol_core::Molecule;
6
7use ::tera::Value;
8// imports:1 ends here
9
10// format
11
12// [[file:~/Workspace/Programming/gchemol-rs/gchemol-readwrite/gchemol-readwrite.note::*format][format:1]]
13fn format_filter(value: &Value, args: &std::collections::HashMap<String, Value>) -> ::tera::Result<Value> {
14    // get keyword parameters
15    let width = args.get("width").and_then(|v| v.as_u64());
16    let prec = args.get("prec").and_then(|v| v.as_u64());
17    let align = args.get("align").and_then(|v| v.as_str()).unwrap_or("");
18    match value {
19        Value::Number(n) => {
20            let w = width.unwrap_or(18) as usize;
21            let p = prec.unwrap_or(8) as usize;
22            let s = match align {
23                "left" => format!("{:<-width$.prec$}", n, width = w, prec = p),
24                "right" => format!("{:>-width$.prec$}", n, width = w, prec = p),
25                "center" => format!("{:^-width$.prec$}", n, width = w, prec = p),
26                _ => format!("{:-width$.prec$}", n, width = w, prec = p),
27            };
28            Ok(s.into())
29        }
30        Value::String(n) => {
31            let w = width.unwrap_or(0) as usize;
32            let s = match align {
33                "left" => format!("{:<-width$}", n, width = w),
34                "right" => format!("{:>-width$}", n, width = w),
35                "center" => format!("{:^-width$}", n, width = w),
36                _ => format!("{:-width$}", n, width = w),
37            };
38            Ok(s.into())
39        }
40        _ => {
41            let s = format!("{:}", value);
42            Ok(s.into())
43        }
44    }
45}
46// format:1 ends here
47
48// impl
49
50// [[file:~/Workspace/Programming/gchemol-rs/gchemol-readwrite/gchemol-readwrite.note::*impl][impl:1]]
51/// render molecule in user defined template
52pub(super) fn render_molecule_with(mol: &Molecule, template: &str) -> Result<String> {
53    use ::tera::{Context, Tera};
54
55    let mut tera = Tera::default();
56    tera.add_raw_template("molecule", template)?;
57    tera.register_filter("format", format_filter);
58
59    let data = renderable(mol);
60    let context = Context::from_value(data)?;
61    tera.render("molecule", &context)
62        .map_err(|e| format_err!("Render molecule failure in tera: {:?}", e))
63}
64// impl:1 ends here