Template.rs
A rust library for making idiomatic, declarative, builder-like patterns that use the struct literal syntax.
No function-like macros required!
How to use
To make a template, just as you would make a builder, you have to consider the following:
- All the parameters
- The default state of the template
- What the template builds into.
- Its relationship with other objects.
You can define a template using the #[template]
annotation
to your template model struct, and the Template
trait.
1. Defining the parameters
Simply use the the #[template]
annotation on a struct with
all the parameters as its fields
2. The default state of the template
By default, this library defines the default state of your
template by #[derive(Default)]
. Custom Default
implementations
are also planned.
3. What the template builds into
Use the Template
trait to define what the template builds into, and how
4. Its relationship with other objects.
Define different default states by dependency injection by objects relative to the template's target.
Using the template
All annotated templates implement the following traits for building the target types:
for<A, F: FnOnce(Self::Output) -> A> FnOnce(F) -> A
FnOnce() -> Self::Output
Those traits can be invoked right after the struct literal in a "currying" fashion.
This is a simple example of idiomatic templates:
Box
// expected result:
// |--------------|---------|
// | Column btn 1 | |
// |--------------| Big Btn |
// | Column btn 2 | |
// |--------------|---------|
In case you don't want to use direct function calls, you can use the following equivalent methods:
fn build<A>(self, F: impl FnOnce(Self::Output) -> A) -> A
fn create(self) -> Self::Output
Box .build
Current Problems and Future Plans
- Allow the user to define custom default states for templates
- Create a
Templatable
trait associates the Output of a template with its template, so that you don't have to associate it yourself. Eg.:
// ...so that
use Box;
Box New ;
- Currently some type analysers do not consider
std::ops::FnOnce
implementations, so they automatically labelStruct { /*...*/ } ( /*...*/ )
syntaxes as wrong when they are perfectly legal and fine as per thestd::ops::FnOnce
trait definition. For example, in the jetbrains Rust Plugin. Until such problems are solved, either use a different analyser, or use the alternative.build()
and.create()
methods.