Skip to content

Commit 1066c88

Browse files
committed
book: add enum documentation
1 parent 5944ab9 commit 1066c88

File tree

2 files changed

+172
-0
lines changed

2 files changed

+172
-0
lines changed

book/src/creating_templates.md

+79
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,85 @@ recognized:
118118
struct HelloTemplate<'a> { ... }
119119
```
120120

121+
## Templating `enum`s
122+
123+
You can add derive `Template`s for `struct`s and `enum`s.
124+
If you add `#[template()]` only to the item itself, both item kinds work exactly the same.
125+
But with `enum`s you also have the option to add a specialized implementation to one, some,
126+
or all variants:
127+
128+
```rust
129+
#[derive(Debug, Template)]
130+
#[template(path = "area.txt")]
131+
enum Area {
132+
Square(f32),
133+
Rectangle { a: f32, b: f32 },
134+
Circle { radius: f32 },
135+
}
136+
```
137+
138+
```jinja2
139+
{%- match self -%}
140+
{%- when Self::Square(side) -%}
141+
{{side}}^2
142+
{%- when Self::Rectangle { a, b} -%}
143+
{{a}} * {{b}}
144+
{%- when Self::Circle { radius } -%}
145+
pi * {{radius}}^2
146+
{%- endmatch -%}
147+
```
148+
149+
will give you the same results as:
150+
151+
```rust
152+
#[derive(Template, Debug)]
153+
#[template(ext = "txt")]
154+
enum AreaPerVariant {
155+
#[template(source = "{{self.0}}^2")]
156+
Square(f32),
157+
#[template(source = "{{a}} * {{b}}")]
158+
Rectangle { a: f32, b: f32 },
159+
#[template(source = "pi * {{radius}}^2")]
160+
Circle { radius: f32 },
161+
}
162+
```
163+
164+
As you can see with the `ext` attribute, `enum` variants inherit most settings of the `enum`:
165+
`config`, `escape`, `ext`, `syntax`, and `whitespace`.
166+
Not inherited are: `block`, and `print`.
167+
168+
If there is no `#[template]` annotation for an `enum` variant,
169+
then the `enum` needs a default implementation, which will be used if `self` is this variant.
170+
A good compromise between annotating only the template, or all its variants,
171+
might be using the `block` argument on the members:
172+
173+
```rust
174+
#[derive(Template, Debug)]
175+
#[template(path = "area.txt")]
176+
enum AreaWithBlocks {
177+
#[template(block = "square")]
178+
Square(f32),
179+
#[template(block = "rectangle")]
180+
Rectangle { a: f32, b: f32 },
181+
#[template(block = "circle")]
182+
Circle { radius: f32 },
183+
}
184+
```
185+
186+
```jinja2
187+
{%- block square -%}
188+
{{self.0}}^2
189+
{%- endblock -%}
190+
191+
{%- block rectangle -%}
192+
{{a}} * {{b}}
193+
{%- endblock -%}
194+
195+
{%- block circle -%}
196+
pi * {{radius}}^2
197+
{%- endblock -%}
198+
```
199+
121200
## Documentation as template code
122201
[#documentation-as-template-code]: #documentation-as-template-code
123202

testing/tests/enum.rs

+93
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,99 @@ use std::fmt::{Debug, Display};
33

44
use rinja::Template;
55

6+
#[test]
7+
fn test_book_example() {
8+
#[derive(Template, Debug)]
9+
#[template(
10+
source = "
11+
{%- match self -%}
12+
{%- when Self::Square(side) -%} {{side}}^2
13+
{%- when Self::Rectangle { a, b} -%} {{a}} * {{b}}
14+
{%- when Self::Circle { radius } -%} pi * {{radius}}^2
15+
{%- endmatch -%}
16+
",
17+
ext = "txt"
18+
)]
19+
enum AreaWithMatch {
20+
#[template(source = "{{self.0}}^2", ext = "txt")]
21+
Square(f32),
22+
#[template(source = "{{a}} * {{b}}", ext = "txt")]
23+
Rectangle { a: f32, b: f32 },
24+
#[template(source = "pi * {{radius}}^2", ext = "txt")]
25+
Circle { radius: f32 },
26+
}
27+
28+
assert_eq!(AreaWithMatch::Square(2.0).render().unwrap(), "2^2");
29+
assert_eq!(
30+
AreaWithMatch::Rectangle { a: 1.0, b: 2.0 }
31+
.render()
32+
.unwrap(),
33+
"1 * 2",
34+
);
35+
assert_eq!(
36+
AreaWithMatch::Circle { radius: 3.0 }.render().unwrap(),
37+
"pi * 3^2"
38+
);
39+
40+
#[derive(Template, Debug)]
41+
enum AreaPerVariant {
42+
#[template(source = "{{self.0}}^2", ext = "txt")]
43+
Square(f32),
44+
#[template(source = "{{a}} * {{b}}", ext = "txt")]
45+
Rectangle { a: f32, b: f32 },
46+
#[template(source = "pi * {{radius}}^2", ext = "txt")]
47+
Circle { radius: f32 },
48+
}
49+
50+
assert_eq!(AreaPerVariant::Square(2.0).render().unwrap(), "2^2");
51+
assert_eq!(
52+
AreaPerVariant::Rectangle { a: 1.0, b: 2.0 }
53+
.render()
54+
.unwrap(),
55+
"1 * 2",
56+
);
57+
assert_eq!(
58+
AreaPerVariant::Circle { radius: 3.0 }.render().unwrap(),
59+
"pi * 3^2"
60+
);
61+
62+
#[derive(Template, Debug)]
63+
#[template(
64+
source = "
65+
{%- block square -%}
66+
{{self.0}}^2
67+
{%- endblock -%}
68+
{%- block rectangle -%}
69+
{{a}} * {{b}}
70+
{%- endblock -%}
71+
{%- block circle -%}
72+
pi * {{radius}}^2
73+
{%- endblock -%}
74+
",
75+
ext = "txt"
76+
)]
77+
enum AreaWithBlocks {
78+
#[template(block = "square")]
79+
Square(f32),
80+
#[template(block = "rectangle")]
81+
Rectangle { a: f32, b: f32 },
82+
#[template(block = "circle")]
83+
Circle { radius: f32 },
84+
}
85+
86+
assert_eq!(AreaWithBlocks::Square(2.0).render().unwrap(), "2^2");
87+
assert_eq!(
88+
AreaWithBlocks::Rectangle { a: 1.0, b: 2.0 }
89+
.render()
90+
.unwrap(),
91+
"1 * 2",
92+
);
93+
assert_eq!(
94+
AreaWithBlocks::Circle { radius: 3.0 }.render().unwrap(),
95+
"pi * 3^2"
96+
);
97+
}
98+
699
#[test]
7100
fn test_simple_enum() {
8101
#[derive(Template, Debug)]

0 commit comments

Comments
 (0)