home ~ projects ~ socials

A Quick MiniJinja Output Script

Version One

This is a quick, stand alone script for outputting data into a template with Rust's MiniJinja crate.

It drops the payload into the TEMPLATE and outputs the result.

#!/usr/bin/env cargo -Zscript

---
[dependencies]
anyhow = "1.0.98"
minijinja = { version = "2.9.0", features = ["custom_syntax"] }
serde = { version = "1.0.219", features = ["derive"] }
---

use anyhow::Result;
use minijinja::{Environment, Value, context};
use minijinja::syntax::SyntaxConfig;
use serde::Serialize;
use std::path::PathBuf;

const TEMPLATE: &str = r#"
[! for item in payload.items !]
Item: [@ item @]
[! endfor !]
"#;

#[derive(Serialize)]
struct Payload {
    items: Vec<String>
}

impl Payload {
    pub fn new() -> Payload{
        let items = vec!["a", "b", "c"]
            .iter()
            .map(|i| i.to_string())
            .collect();
        Payload{
            items 
        }
    }
}

fn main() -> Result<()> {
    let output_path = PathBuf::from(
        "../src/span_attr/span_add_key_token_tests.rs"
    );
    let payload = Payload::new();
    let content = generate_output(payload)?;
    println!("{}", &content);
    std::fs::write(output_path, content)?;
    Ok(())
}

fn generate_output(payload: Payload) -> Result<String> {
    let mut env = Environment::new();
    env.set_syntax(
        SyntaxConfig::builder()
            .block_delimiters("[!", "!]")
            .variable_delimiters("[@", "@]")
            .comment_delimiters("[#", "#]")
            .build()
            .unwrap(),
    );
    env.add_template(
        "skeleton", TEMPLATE
    )?;
    let template = env.get_template("skeleton")?;
    let output = template.render(context!(
        payload => Value::from_serialize(payload)
    ))?;
    Ok(output)
}

fn write_with_mkdir(path: &PathBuf, content: &str) -> Result<()> {
  let parent_dir = path.parent().ok_or(
    std::io::Error::other("Could not get parent path")
  )?;
  std::fs::create_dir_all(parent_dir)?;
  std::fs::write(path, content)?;
  Ok(())
}

Notes

  • This script can be run directly from the command line without having to build a binary. It does that by utilizing -Zscript.
  • You can either do chmod u+x YOUR_FILE_NAME.rs on the script and run it with ./YOUR_FILE_NAME.rs. Or you can run it with cargo -Zscript YOUR_FILE_NAME.rs.
  • You might have to have to be using Rust's "Nightly" version to get it to work. (I don't have the spoons to check that at the moment)
-- end of line --