just_template
A template engine for code generation.
Template syntax
Simple parameters — <<<key>>>
The most basic substitution. Replaced with the value set via
[Template::insert_param] or the [tmpl!] macro.
# use just_template::Template;
let mut t = Template::from("Hello, <<<name>>>!".to_string());
t.insert_param("name".to_string(), "World".to_string());
assert_eq!(t.expand().unwrap(), "Hello, World!");
Implementation blocks
Syntax: >>>>>>>>>> name / @@@ >>> name ... @@@ <<<
Template sections that can be instantiated multiple times with different parameter sets. Each instantiation is called an "arm".
# use just_template::Template;
let mut t = Template::from(r#"
>>>>>>>>>> match_arms
@@@ >>> match_arms
<<<value>>> => println!("<<<value>>>"),
@@@ <<<
"#.trim().to_string());
let arms = t.add_impl("match_arms".to_string());
arms.push(std::collections::HashMap::from([
("value".to_string(), "a".to_string()),
]));
arms.push(std::collections::HashMap::from([
("value".to_string(), "b".to_string()),
]));
let out = t.expand().unwrap();
assert!(out.contains(r#"a => println!("a")"#));
assert!(out.contains(r#"b => println!("b")"#));
Display blocks
Syntax: ??? >>> name / ??? <<<
Conditionally included sections. Hidden by default; shown when a parameter with the same name exists in the parameter map.
# use just_template::Template;
// Without enabling, the block is omitted
let t = Template::from(r#"
visible
??? >>> debug
hidden by default
??? <<<
"#.trim().to_string());
assert_eq!(t.expand().unwrap(), "visible");
// Enable by inserting a param with the block name
let mut t = Template::from(r#"
visible
??? >>> debug
hidden by default
??? <<<
"#.trim().to_string());
t.insert_param("debug".to_string(), "".to_string());
let out = t.expand().unwrap();
assert!(out.contains("hidden by default"));
Display blocks also work inside implementation blocks, and can be controlled per arm by including the block name in that arm's parameter map:
# use just_template::Template;
let mut t = Template::from(r#"
>>>>>>>>>> arms
@@@ >>> arms
<<<name>>>
??? >>> extra
<<<name>>>.extra()
??? <<<
@@@ <<<
"#.trim().to_string());
let arms = t.add_impl("arms".to_string());
// Arm 1: no "extra" → display block hidden
arms.push(std::collections::HashMap::from([
("name".to_string(), "foo".to_string()),
]));
// Arm 2: has "extra" → display block shown for this arm only
arms.push(std::collections::HashMap::from([
("name".to_string(), "bar".to_string()),
("extra".to_string(), "".to_string()),
]));
let out = t.expand().unwrap();
assert!(out.contains("foo"));
assert!(!out.contains("foo.extra()"));
assert!(out.contains("bar"));
assert!(out.contains("bar.extra()"));
The tmpl! macro
The tmpl! proc macro provides a concise syntax for
setting both simple parameters and implementation blocks.
# use just_template::{Template, tmpl};
let mut t = Template::from(r#"
>>>>>>>>>> arms
@@@ >>> arms
<<<crate_name>>> => Some(<<<crate_name>>>::exec(data, params).await),
@@@ <<<
"#.trim().to_string());
# let param: i32 = 1; // dummy
tmpl!(t,
func_name = "my_func",
arms {
crate_name = "my",
{
crate_name = "you",
extra = ""
}
}
);
When the template variable is named tmpl, it can be omitted:
# use just_template::{Template, tmpl};
let mut tmpl = Template::from("<<<a>>> + <<<b>>> = <<<c>>>".to_string());
tmpl! {
a = "1",
b = "2",
c = "3",
};
assert_eq!(tmpl.expand().unwrap(), "1 + 2 = 3");
Installation
Add this to your Cargo.toml:
[dependencies]
just_template = "0.2"
License
This project is dual-licensed under MIT and Apache 2.0. See the LICENSE file for details.
