7 releases (stable)

3.0.1 Feb 20, 2024
3.0.0 Feb 12, 2024
2.0.1 Jun 26, 2023
2.0.0 Apr 26, 2023
0.0.0 Feb 5, 2023

#37 in Template engine

Download history 1282/week @ 2023-12-18 675/week @ 2023-12-25 1267/week @ 2024-01-01 1689/week @ 2024-01-08 1257/week @ 2024-01-15 1345/week @ 2024-01-22 1300/week @ 2024-01-29 1624/week @ 2024-02-05 1718/week @ 2024-02-12 1973/week @ 2024-02-19 2172/week @ 2024-02-26 2139/week @ 2024-03-04 1627/week @ 2024-03-11 1904/week @ 2024-03-18 1533/week @ 2024-03-25 1580/week @ 2024-04-01

6,790 downloads per month
Used in 12 crates (9 directly)

Apache-2.0 OR MIT

37KB
819 lines

leon

Dead-simple string templating.

Check here for latest documentation.


lib.rs:

Dead-simple string templating.

Leon parses a template string into a list of tokens, and then substitutes provided values in. Unlike other templating engines, it is extremely simple: it supports no logic, only replaces. It is even simpler than format!(), albeit with a similar syntax.

Syntax

it is better to rule { group }
one can live {adverb} without power

A replacement is denoted by { and }. The contents of the braces, trimmed of any whitespace, are the key. Any text outside of braces is left as-is.

To escape a brace, use \{ or \}. To escape a backslash, use \\. Keys cannot contain escapes.

\{ leon \}

The above examples, given the values group = "no one" and adverb = "honourably", would render to:

it is better to rule no one
one can live honourably without power
{ leon }

Usage

A template is first parsed to a token list:

use leon::Template;

let template = Template::parse("hello {name}").unwrap();

The template can be inspected, for example to check if a key is present:

#
assert!(template.has_key("name"));

The template can be rendered to a string:

use leon::vals;
#
assert_eq!(
    template.render(
        &&vals(|_key| Some("marcus".into()))
    ).unwrap().as_str(),
    "hello marcus",
);

…or to a writer:

use std::io::Write;
use leon::vals;
#
let mut buf: Vec<u8> = Vec::new();
template.render_into(
    &mut buf,
    &&vals(|key| if key == "name" {
        Some("julius".into())
    } else {
        None
    })
).unwrap();
assert_eq!(buf.as_slice(), b"hello julius");

…with a map:

use std::collections::HashMap;
let mut values = HashMap::new();
values.insert("name", "brutus");
assert_eq!(template.render(&values).unwrap().as_str(), "hello brutus");

…or with your own type, if you implement the Values trait:

use std::borrow::Cow;
use leon::Values;

struct MyMap {
  name: &'static str,
}
impl Values for MyMap {
   fn get_value(&self, key: &str) -> Option<Cow<'_, str>> {
      if key == "name" {
        Some(self.name.into())
     } else {
       None
    }
   }
}
#
let values = MyMap { name: "pontifex" };
assert_eq!(template.render(&values).unwrap().as_str(), "hello pontifex");

Compile-time parsing

You can either use leon-macros's template!, a proc-macro, with the exact same syntax as the normal parser, or this crate's template! rules-macro, which requires a slightly different syntax but doesn't bring in additional dependencies. In either case, the leon library is required as a runtime dependency.

Errors

Leon will return a ParseError if the template fails to parse. This can happen if there are unbalanced braces, or if a key is empty.

Leon will return a RenderError::MissingKey if a key is missing from keyed values passed to [Template::render()], unless a default value is provided with Template.default.

It will also pass through I/O errors when using [Template::render_into()].

Dependencies

~0.7–11MB
~105K SLoC