1use crate::image::Image;
5use crate::list::List;
6use crate::style::{Align, Border, Color, Common, FontKey, Overflow, TextStyle};
7use crate::table::Table;
8
9#[derive(Clone, Debug)]
12pub enum Element {
13 Text(Text),
14 Row(Row),
15 Column(Column),
16 Spacer(Spacer),
17 Line(Line),
18 Rect(Rect),
19 Table(Table),
20 Image(Image),
21 List(List),
22 PageBreak,
25}
26
27impl Element {
28 pub fn common(&self) -> Option<&Common> {
31 match self {
32 Element::Text(t) => Some(&t.common),
33 Element::Row(r) => Some(&r.common),
34 Element::Column(c) => Some(&c.common),
35 Element::Line(l) => Some(&l.common),
36 Element::Rect(r) => Some(&r.common),
37 Element::Table(t) => Some(&t.common),
38 Element::Image(i) => Some(&i.common),
39 Element::List(l) => Some(&l.common),
40 Element::Spacer(_) | Element::PageBreak => None,
41 }
42 }
43
44 pub fn common_mut(&mut self) -> Option<&mut Common> {
48 match self {
49 Element::Text(t) => Some(&mut t.common),
50 Element::Row(r) => Some(&mut r.common),
51 Element::Column(c) => Some(&mut c.common),
52 Element::Line(l) => Some(&mut l.common),
53 Element::Rect(r) => Some(&mut r.common),
54 Element::Table(t) => Some(&mut t.common),
55 Element::Image(i) => Some(&mut i.common),
56 Element::List(l) => Some(&mut l.common),
57 Element::Spacer(_) | Element::PageBreak => None,
58 }
59 }
60}
61
62macro_rules! common_builder_methods {
66 () => {
67 pub fn width(mut self, width: f32) -> Self {
68 self.common.width = Some(width);
69 self
70 }
71
72 pub fn height(mut self, height: f32) -> Self {
73 self.common.height = Some(height);
74 self
75 }
76
77 pub fn flex(mut self, factor: f32) -> Self {
78 self.common.flex = Some(factor);
79 self
80 }
81
82 pub fn padding(mut self, padding: f32) -> Self {
83 self.common.padding = padding;
84 self
85 }
86
87 pub fn overflow(mut self, overflow: Overflow) -> Self {
88 self.common.overflow = overflow;
89 self
90 }
91
92 pub fn background(mut self, color: Color) -> Self {
93 self.common.background = Some(color);
94 self
95 }
96
97 pub fn border(mut self, border: Border) -> Self {
98 self.common.border = Some(border);
99 self
100 }
101
102 pub fn keep_with_next(mut self) -> Self {
105 self.common.keep_with_next = true;
106 self
107 }
108 };
109}
110
111#[derive(Clone, Debug, Default)]
116pub struct Text {
117 pub content: String,
118 pub style: TextStyle,
119 pub common: Common,
120}
121
122impl Text {
123 pub fn new(content: impl Into<String>) -> Self {
124 Text {
125 content: content.into(),
126 style: TextStyle::default(),
127 common: Common::default(),
128 }
129 }
130
131 pub fn size(mut self, size: f32) -> Self {
132 self.style.size = size;
133 self
134 }
135
136 pub fn bold(mut self) -> Self {
137 self.style.font = FontKey::SANS_BOLD;
138 self
139 }
140
141 pub fn font(mut self, font: FontKey) -> Self {
142 self.style.font = font;
143 self
144 }
145
146 pub fn color(mut self, color: Color) -> Self {
147 self.style.color = color;
148 self
149 }
150
151 pub fn align(mut self, align: Align) -> Self {
152 self.style.align = align;
153 self
154 }
155
156 pub fn line_height(mut self, line_height: f32) -> Self {
157 self.style.line_height = line_height;
158 self
159 }
160
161 pub fn heading1(self) -> Self {
167 self.size(24.0).bold().keep_with_next()
168 }
169
170 pub fn heading2(self) -> Self {
171 self.size(18.0).bold().keep_with_next()
172 }
173
174 pub fn heading3(self) -> Self {
175 self.size(14.0).bold().keep_with_next()
176 }
177
178 common_builder_methods!();
179}
180
181impl From<&str> for Text {
182 fn from(value: &str) -> Self {
183 Text::new(value)
184 }
185}
186
187impl From<String> for Text {
188 fn from(value: String) -> Self {
189 Text::new(value)
190 }
191}
192
193#[derive(Clone, Debug, Default)]
198pub struct Row {
199 pub children: Vec<Element>,
200 pub gap: f32,
201 pub align: Align,
202 pub common: Common,
203}
204
205#[derive(Clone, Debug, Default)]
206pub struct Column {
207 pub children: Vec<Element>,
208 pub gap: f32,
209 pub align: Align,
210 pub common: Common,
211}
212
213macro_rules! container_impl {
214 ($ty:ident) => {
215 impl $ty {
216 pub fn new() -> Self {
217 Self::default()
218 }
219
220 pub fn child(mut self, child: impl Into<Element>) -> Self {
221 self.children.push(child.into());
222 self
223 }
224
225 pub fn children(mut self, children: impl IntoIterator<Item = impl Into<Element>>) -> Self {
226 self.children.extend(children.into_iter().map(Into::into));
227 self
228 }
229
230 pub fn gap(mut self, gap: f32) -> Self {
231 self.gap = gap;
232 self
233 }
234
235 pub fn align(mut self, align: Align) -> Self {
236 self.align = align;
237 self
238 }
239
240 common_builder_methods!();
241 }
242 };
243}
244
245container_impl!(Row);
246container_impl!(Column);
247
248#[derive(Clone, Copy, Debug)]
253pub struct Spacer {
254 pub size: f32,
255}
256
257impl Spacer {
258 pub fn new(size: f32) -> Self {
259 Spacer { size }
260 }
261}
262
263#[derive(Clone, Debug)]
268pub struct Line {
269 pub thickness: f32,
270 pub color: Color,
271 pub common: Common,
272}
273
274impl Default for Line {
275 fn default() -> Self {
276 Line {
277 thickness: 1.0,
278 color: Color::BLACK,
279 common: Common::default(),
280 }
281 }
282}
283
284impl Line {
285 pub fn new() -> Self {
286 Self::default()
287 }
288
289 pub fn thickness(mut self, thickness: f32) -> Self {
290 self.thickness = thickness;
291 self
292 }
293
294 pub fn color(mut self, color: Color) -> Self {
295 self.color = color;
296 self
297 }
298
299 common_builder_methods!();
300}
301
302#[derive(Clone, Debug, Default)]
307pub struct Rect {
308 pub common: Common,
309}
310
311impl Rect {
312 pub fn new() -> Self {
313 Self::default()
314 }
315
316 common_builder_methods!();
317}
318
319macro_rules! element_from {
324 ($ty:ident) => {
325 impl From<$ty> for Element {
326 fn from(value: $ty) -> Self {
327 Element::$ty(value)
328 }
329 }
330 };
331}
332
333element_from!(Text);
334element_from!(Row);
335element_from!(Column);
336element_from!(Spacer);
337element_from!(Line);
338element_from!(Rect);
339element_from!(Table);
340element_from!(Image);
341element_from!(List);
342
343impl From<&str> for Element {
344 fn from(value: &str) -> Self {
345 Element::Text(Text::new(value))
346 }
347}
348
349impl From<String> for Element {
350 fn from(value: String) -> Self {
351 Element::Text(Text::new(value))
352 }
353}