Coming from Go I'm wondering if there is an easy way to natively generate code (or files) like I do in Go using only
It's very easy to generate code with Go like this.
Is there a similar way in Rust or I should search for 3rd party template engine?
In rust we would use generics and/or macros.
Generally codegen is Rust is done via frequent calls to
Im not using templating for Go code only. I'm using it to generate other files too. So in Rust there is nothing like that right?
And are there 3rd party template engines?
What are you generating then ? You could use the
build.rs file to do that.
There are lots of 3rd party template engines, but nothing in the std lib besides
std::fmt as noted previously, most of the generated code i've run across doesn't use a template library.
minijinja once, for generating rust code, but that was providing a rust based alternative to existing python tools, while also using existing templates generating c-code, adding templates generating rust-code...
This wasn't in a cargo based build, but that would be easy via build.rs as noted above. But overall it was successful, in that I can now run the code generation on either python with
jinja, or rust with
minijinja, so we can do a nice orderly transition (perhaps).
Anyhow, to answer your question: yes, there are 3rd party templating engines (many of them), but i've rarely seen then used for codegen except in this case where there was an existing template based codegen mechanism...
And that's probably because macros and generics are powerful enough for most "codegen" type tasks.
But I'm not referring to Rust code only. I'm referring to things like scaffolding an entire project, with typescript, yaml, svg files and other things too.
I think using
std::fmt for this is very difficult.
To answer your question directly, I've had great experiences using
tera. That said, you can get surprisingly far by just using
std::io::Write and the
To understand why there is no
text/template module in
std, it might help to understand the differences in philosophy and background between Go and Rust.
Go prefers to come with batteries included, giving you everything you need to implement a web server without any 3rd party libraries. However, for Rust the standard library is intended to have the bare essentials for writing a program (typically a CLI program or library) that is cross-platform by default. These are things like...
- Data structures which almost all Rust programs will need (
- Core abstractions that are required to implement the language (slices,
std::fmt and its associated macros, etc.)
- Cross-platform abstractions over the OS (
All of these tend to have 1 obvious implementation and you wouldn't be able to write a Rust program without them (imagine the chaos if
Vec had to come from 3rd party libraries ).
For a counter example, on crates.io alone there are 179 crates in the "Templating Engine" category that all have different designs and trade-offs. Given our previously stated philosophy, for a Rustacean it wouldn't make sense to have a
text/template module in the standard library.
I'm not saying that one philosophy is better than the other, but sometimes knowing more about the history can help you understand why certain decisions were made and avoid getting frustrated when a language does things differently to what you are used to.