md-tmpl-macros
Proc macros for build-time template validation, pre-parsing, and typed parameter struct generation for md-tmpl.
Why?
The core md-tmpl crate validates at runtime. This companion
crate moves validation to cargo build — syntax errors, unknown
variables, and type mismatches become build errors. It also generates
typed Rust structs from frontmatter. Templates can still be loaded at
runtime for dynamic or hot-reload use cases.
Installation
Macros
include_template!
Reads, parses, and validates a .tmpl.md file at build time. Emits a
module with the pre-parsed template, typed parameter struct, sub-structs,
constants, and type aliases.
use include_template;
include_template!;
let output = Params
.render
.unwrap;
assert_eq!;
Override the module name:
use include_template;
include_template!;
let output = Params
.render
.unwrap;
assert_eq!;
Generated module contents
pub fn template() -> &'static Template— pre-parsed template singleton.pub struct Params { ... }— typed parameter struct with:render()— render using the embedded template.render_reloaded(tmpl)— render with an externally-loaded template (hot-reload).validate_template(tmpl)— check template compatibility.to_context()— convert to aContext.
- Sub-structs for compound types (e.g.
ParamsItemsItem). - Constants from the
consts:block. - Type aliases / enums from the
types:block.
template!
Like include_template!, but for inline template strings. The
=> module_name is required.
template!;
let output = Params
.render
.unwrap;
assert_eq!;
Hot-Reload with Type Safety
Combine build-time types with runtime loading — iterate on prompt wording without recompiling, while keeping your type guarantees:
use Template;
include_template!;
// Load from disk at runtime:
let tmpl = from_file.unwrap;
// Validate the reloaded file hasn't diverged:
validate_template.unwrap;
// Render with the disk-loaded template:
let output = Params .render_reloaded.unwrap;
Type Mapping
| Frontmatter Type | Rust Type |
|---|---|
str |
String |
int |
i64 |
float |
f64 |
bool |
bool |
list(field = type, ...) |
Vec<Params{Field}Item> (auto-generated sub-struct) |
struct(field = type, ...) |
Params{Field} (auto-generated sub-struct) |
enum(Variant, ...) |
Params{Field} (auto-generated enum) |
option(T) |
Option<RustType> |
tmpl(field = type, ...) |
Params{Field} (template callable) |
License
Apache-2.0 OR MIT