Overview
This crate defines a simple templating language in the format %(SELECTOR) that
can operate on a structure. A given SELECTOR accesses a given structure of
type T via a closure Fn(&T) -> Option<String>. Using a closure allows
complex logic to accessing the structure e.g. "if field x does not exist,
then try field y, otherwise return a default value or None".
(This library is most definitely not production-ready)
Terminology
- A template is a string
%(X)whereXis a selector - A selector is any string (including the empty string) without a round, closing parenthesis
) - The closure associated with a given selector is known as an accessor
- A format string is a string containing zero or more templates with other non-templating characters e.g.
%(id) - %(title)
Quick Start
In Cargo.toml:
[dependencies]
struct_string_template = "0.1.0"
Say we have a struct definition, and an instance of the struct:
let my_book = Book ;
Define a format string:
let format_string = "[%(id)] %(title) %(所有作者)";
Build a Templater<Book> by doing:
use TemplaterBuilder;
let templater = new
.with_selector
.with_selector
.with_selector
.build;
Render it using Templater's render function
let result = templater.render.ok.unwrap;
println!;
Advanced Use
Building Templater without TemplateBuilder
If the Templater needs to be built iteratively instead of using the builder
class, use Templater::new(), then add closures using the insert or extend
methods.
let mut templater = new;
templater.insert;
templater.insert;
templater.insert;
Formatter
If you plan to use a format string many times, you can "precompile" it similar
to a regex for better performance using the Formatter class (render turns
the format string into a Formatter internally), then pass the Formatter
variable into the renderf function:
use Formatter;
let formatter = build.ok.unwrap;
let result = templater.renderf;
println!;
Error Handling
See src/err.rs for the errors thrown.
Template Rules
In this section, X is any selector
%%is treated as a literal%%followed by a character (or end of string) that is not(is invalid%(X)is always valid%(X)AwhereAis any valid string is valid%(X(template is not terminated) is invalid- Having no closure associated with
Xis invalid - If the return value of the closure of
Xon the structure isNone,NAis printed. This is currently unconfigurable except by modifying the closure itself.
Limitations
Currently the Templater object cannot be copied around due to the closure
types. I've not found a work-around for this yet.
Motivation
I use this library in a few personal applications of mine, and I've found it annoying to keep changes to the library in sync between them.