#compile-time #macro-derive #run-time #statically-checked

macro no-std boilerplate

Minimal compile-time Rust template engine

11 releases (1 stable)

1.0.0 Jul 5, 2023
0.2.5 Jan 2, 2023
0.2.4 Dec 28, 2022
0.2.1 Oct 4, 2022
0.0.0 Feb 13, 2017

#433 in Template engine

Download history 547/week @ 2024-01-03 523/week @ 2024-01-10 706/week @ 2024-01-17 1027/week @ 2024-01-24 918/week @ 2024-01-31 590/week @ 2024-02-07 629/week @ 2024-02-14 495/week @ 2024-02-21 483/week @ 2024-02-28 607/week @ 2024-03-06 485/week @ 2024-03-13 638/week @ 2024-03-20 926/week @ 2024-03-27 866/week @ 2024-04-03 2366/week @ 2024-04-10 1842/week @ 2024-04-17

6,124 downloads per month
Used in 6 crates (5 directly)

CC0 license

30KB
433 lines

boilerplate


boilerplate is a statically-checked Rust template engine with no runtime dependencies. There are two ways to use boilerplate, boilerplate::boilerplate, a function-like macro, and boilerplate::Boilerplate, a derive macro.

Function-like Macro

use boilerplate::boilerplate;

let foo = true;
let bar: Result<&str, &str> = Ok("yassss");

let output = boilerplate!(
"%% if foo {
Foo was true!
%% }
%% match bar {
%%   Ok(ok) => {
Pretty good: {{ ok }}
%%   }
%%   Err(err) => {
Not so great: {{ err }}
%%   }
%% }
");

assert_eq!(output, "Foo was true!\nPretty good: yassss\n");

Derive Macro

Derive Boilerplate on the type you want to use as a template context:

use boilerplate::Boilerplate;

#[derive(Boilerplate)]
struct MyTemplateTxt {
  foo: bool,
  bar: Result<String, Box<dyn std::error::Error>>,
}

boilerplate template code and interpolations are Rust, so errors are checked at compile time and the template language is easy to learn:

%% if self.foo {
Foo was true!
%% }
%% match &self.bar {
%%   Ok(ok) => {
Pretty good: {{ ok }}
%%   }
%%   Err(err) => {
Not so great: {{ err }}
%%   }
%% }

The Boilerplate macro provides a Display implementation, so you can instantiate a template context and convert it to a string:

let rendered = MyTemplateTxt { foo: true, bar: Ok("hello".into()) }.to_string();

Or use it in a format string:

println!("The output is: {}", MyTemplateTxt { foo: false, bar: Err("hello".into()) });

boilerplate's implementation is exceedingly simple. Try using cargo-expand to expand the Boilerplate macro and inspect derived Display implementations and debug template issues.

Quick Start

Add boilerplate to your project's Cargo.toml:

[dependencies]
boilerplate = "*"

Create a template in templates/my-template.txt:

Foo is {{self.n}}!

Define, instantiate, and render the template context:

use boilerplate::Boilerplate;

#[derive(Boilerplate)]
struct MyTemplateTxt {
  n: u32,
}

assert_eq!(MyTemplateTxt  { n: 10 }.to_string(), "Foo is 10!\n");

Examples

See the docs for more information and examples.

Dependencies

~0.9–1.3MB
~30K SLoC