7 releases (4 breaking)

0.5.0 Apr 17, 2023
0.4.0 Mar 1, 2023
0.3.0 Mar 1, 2023
0.2.0 Feb 28, 2023
0.1.2 Feb 27, 2023

#64 in Template engine

Download history 43531/week @ 2024-01-12 46165/week @ 2024-01-19 37253/week @ 2024-01-26 42318/week @ 2024-02-02 44016/week @ 2024-02-09 41772/week @ 2024-02-16 52433/week @ 2024-02-23 55075/week @ 2024-03-01 43504/week @ 2024-03-08 43499/week @ 2024-03-15 50357/week @ 2024-03-22 59091/week @ 2024-03-29 58112/week @ 2024-04-05 66247/week @ 2024-04-12 63103/week @ 2024-04-19 47978/week @ 2024-04-26

247,839 downloads per month
Used in 182 crates (via attribute-derive-macro)


3.5K SLoC


CI Status Documentation for main Crates.io Docs.rs

Runtime implementation of format!.


Runtime version of format!.

Takes a string and a context, containing Formattable values, returns a string.

use std::collections::HashMap;
use template::{format, Formattable};

let formatted = format(
    "{value:+05}", // could be dynamic
    &[("value", Formattable::display(&12))].into_iter().collect::<HashMap<_,_>>(),

assert_eq!(formatted, format!("{:+05}", 12));


Runtime version of write!.

Takes a mutable Write e.g. &mut String, a format string and a context, containing Formattable values.

use std::collections::HashMap;
use template::{write, Formattable};
let mut buf = String::new();
    &mut buf,
    "{value:+05}", // could be dynamic
    &[("value", Formattable::display(&12))].into_iter().collect::<HashMap<_,_>>(),
assert_eq!(buf, format!("{:+05}", 12));

i iter format

The feature iter enables an additional format trait i, it allows to format a list of values with a format string and an optional join expression.

The syntax is {list:i(the format string, '{}' is the array element)(the join)}, an empty join can also be omitted {list:i({})}. If join is omitted the format string {} can be omitted as well {list:i}.

Should you need to use ) inside your format string or join, you can add # similar to rust's raw string (i.e. #(({}))#).

It is also possible to only iterate a sub-slice specified through a range before the format string, i.e. {list:i1..4}. For open ranges range bounds can also be omitted. To index from the end, you can use negative range bounds.

It is also possible to index a single value by only specifying an isize {list:i1}.

A Formattable implementing iter is created using Formattable::iter:

// HashMap macro
use collection_literals::hash;
use interpolator::{format, Formattable};
// Needs to be a slice of references because `Formattable::display` expects a
// reference
let items = [&"hello", &"hi", &"hey"].map(Formattable::display);
let items = Formattable::iter(&items);
let format_str = "Greetings: {items:i..-1(`{it}`)(, )} and {items:i-1..(`{it}`)}";
    format(format_str, &hash!("items" => items))?,
    "Greetings: `hello`, `hi` and `hey`"
# return Ok::<(), interpolator::Error>(())


By default only Display is supported, the rest of the formatting traits can be enabled through the following features.

  • debug enables ?, x? and X? trait specifiers
  • number enables x, X, b, o, e and E trait specifiers
  • pointer enables p trait specifiers
  • iter enables i trait specifier

No runtime deps