1#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
7pub enum Display {
8 #[default]
10 Flex,
11 Block,
13 Grid,
15 None,
17}
18
19#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
21pub enum Position {
22 #[default]
24 Static,
25 Relative,
27 Absolute,
29 Fixed,
31}
32
33#[derive(Debug, Clone, Default, PartialEq)]
35pub enum GridTrack {
36 Fixed(u16),
38 Fr(f32),
40 #[default]
42 Auto,
43 MinContent,
45 MaxContent,
47}
48
49#[derive(Debug, Clone, Default, PartialEq)]
51pub struct GridTemplate {
52 pub tracks: Vec<GridTrack>,
54}
55
56impl GridTemplate {
57 pub fn new(tracks: Vec<GridTrack>) -> Self {
59 Self { tracks }
60 }
61
62 pub fn repeat(count: usize, track: GridTrack) -> Self {
64 Self {
65 tracks: vec![track; count],
66 }
67 }
68
69 pub fn fr(values: &[f32]) -> Self {
71 Self {
72 tracks: values.iter().map(|&v| GridTrack::Fr(v)).collect(),
73 }
74 }
75
76 pub fn fixed(values: &[u16]) -> Self {
78 Self {
79 tracks: values.iter().map(|&v| GridTrack::Fixed(v)).collect(),
80 }
81 }
82}
83
84#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
86pub struct GridPlacement {
87 pub start: i16,
89 pub end: i16,
91}
92
93impl GridPlacement {
94 pub fn auto() -> Self {
96 Self { start: 0, end: 0 }
97 }
98
99 pub fn line(line: i16) -> Self {
101 Self {
102 start: line,
103 end: 0,
104 }
105 }
106
107 pub fn span(count: i16) -> Self {
109 Self {
110 start: 0,
111 end: -count,
112 } }
114
115 pub fn from_to(start: i16, end: i16) -> Self {
117 Self { start, end }
118 }
119}
120
121#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
123pub enum FlexDirection {
124 #[default]
126 Row,
127 Column,
129}
130
131#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
133pub enum JustifyContent {
134 #[default]
136 Start,
137 Center,
139 End,
141 SpaceBetween,
143 SpaceAround,
145}
146
147#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
149pub enum AlignItems {
150 #[default]
152 Start,
153 Center,
155 End,
157 Stretch,
159}
160
161#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
163pub struct Spacing {
164 pub top: u16,
166 pub right: u16,
168 pub bottom: u16,
170 pub left: u16,
172}
173
174impl Spacing {
175 pub fn all(value: u16) -> Self {
177 Self {
178 top: value,
179 right: value,
180 bottom: value,
181 left: value,
182 }
183 }
184
185 pub fn vertical(value: u16) -> Self {
187 Self {
188 top: value,
189 right: 0,
190 bottom: value,
191 left: 0,
192 }
193 }
194
195 pub fn horizontal(value: u16) -> Self {
197 Self {
198 top: 0,
199 right: value,
200 bottom: 0,
201 left: value,
202 }
203 }
204
205 pub fn new(top: u16, right: u16, bottom: u16, left: u16) -> Self {
207 Self {
208 top,
209 right,
210 bottom,
211 left,
212 }
213 }
214}
215
216#[derive(Debug, Clone, Copy, Default, PartialEq)]
218pub enum Size {
219 #[default]
221 Auto,
222 Fixed(u16),
224 Percent(f32),
226}
227
228#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
230pub enum BorderStyle {
231 #[default]
233 None,
234 Solid,
236 Dashed,
238 Double,
240 Rounded,
242}
243
244#[derive(Debug, Clone, Copy, PartialEq, Eq)]
249pub struct Color {
250 pub r: u8,
252 pub g: u8,
254 pub b: u8,
256 pub a: u8,
258}
259
260impl Default for Color {
261 fn default() -> Self {
263 Self {
264 r: 0,
265 g: 0,
266 b: 0,
267 a: 0,
268 }
269 }
270}
271
272#[derive(Debug, Clone)]
274pub enum Property {
275 Display(Display),
277 FlexDirection(FlexDirection),
279 Padding(Spacing),
281 Margin(Spacing),
283 Color(Color),
285 Background(Color),
287 BorderStyle(BorderStyle),
289 BorderColor(Color),
291}
292
293#[cfg(test)]
294mod tests {
295 use super::*;
296
297 #[test]
299 fn test_display_default() {
300 assert_eq!(Display::default(), Display::Flex);
301 }
302
303 #[test]
304 fn test_display_variants() {
305 assert_eq!(Display::Flex, Display::Flex);
306 assert_eq!(Display::Block, Display::Block);
307 assert_eq!(Display::Grid, Display::Grid);
308 assert_eq!(Display::None, Display::None);
309 }
310
311 #[test]
313 fn test_position_default() {
314 assert_eq!(Position::default(), Position::Static);
315 }
316
317 #[test]
318 fn test_position_variants() {
319 assert_eq!(Position::Static, Position::Static);
320 assert_eq!(Position::Relative, Position::Relative);
321 assert_eq!(Position::Absolute, Position::Absolute);
322 assert_eq!(Position::Fixed, Position::Fixed);
323 }
324
325 #[test]
327 fn test_grid_track_default() {
328 assert_eq!(GridTrack::default(), GridTrack::Auto);
329 }
330
331 #[test]
332 fn test_grid_track_fixed() {
333 let track = GridTrack::Fixed(10);
334 assert_eq!(track, GridTrack::Fixed(10));
335 }
336
337 #[test]
338 fn test_grid_track_fr() {
339 let track = GridTrack::Fr(1.5);
340 assert_eq!(track, GridTrack::Fr(1.5));
341 }
342
343 #[test]
344 fn test_grid_track_min_content() {
345 let track = GridTrack::MinContent;
346 assert_eq!(track, GridTrack::MinContent);
347 }
348
349 #[test]
350 fn test_grid_track_max_content() {
351 let track = GridTrack::MaxContent;
352 assert_eq!(track, GridTrack::MaxContent);
353 }
354
355 #[test]
357 fn test_grid_template_default() {
358 let template = GridTemplate::default();
359 assert!(template.tracks.is_empty());
360 }
361
362 #[test]
363 fn test_grid_template_new() {
364 let template = GridTemplate::new(vec![GridTrack::Fixed(10), GridTrack::Fr(1.0)]);
365 assert_eq!(template.tracks.len(), 2);
366 }
367
368 #[test]
369 fn test_grid_template_repeat() {
370 let template = GridTemplate::repeat(3, GridTrack::Fixed(10));
371 assert_eq!(template.tracks.len(), 3);
372 assert!(template.tracks.iter().all(|t| t == &GridTrack::Fixed(10)));
373 }
374
375 #[test]
376 fn test_grid_template_fr() {
377 let template = GridTemplate::fr(&[1.0, 2.0, 1.5]);
378 assert_eq!(template.tracks.len(), 3);
379 assert_eq!(template.tracks[0], GridTrack::Fr(1.0));
380 assert_eq!(template.tracks[1], GridTrack::Fr(2.0));
381 assert_eq!(template.tracks[2], GridTrack::Fr(1.5));
382 }
383
384 #[test]
385 fn test_grid_template_fixed() {
386 let template = GridTemplate::fixed(&[10, 20, 30]);
387 assert_eq!(template.tracks.len(), 3);
388 assert_eq!(template.tracks[0], GridTrack::Fixed(10));
389 assert_eq!(template.tracks[1], GridTrack::Fixed(20));
390 assert_eq!(template.tracks[2], GridTrack::Fixed(30));
391 }
392
393 #[test]
395 fn test_grid_placement_default() {
396 let placement = GridPlacement::default();
397 assert_eq!(placement.start, 0);
398 assert_eq!(placement.end, 0);
399 }
400
401 #[test]
402 fn test_grid_placement_auto() {
403 let placement = GridPlacement::auto();
404 assert_eq!(placement.start, 0);
405 assert_eq!(placement.end, 0);
406 }
407
408 #[test]
409 fn test_grid_placement_line() {
410 let placement = GridPlacement::line(5);
411 assert_eq!(placement.start, 5);
412 assert_eq!(placement.end, 0);
413 }
414
415 #[test]
416 fn test_grid_placement_span() {
417 let placement = GridPlacement::span(3);
418 assert_eq!(placement.start, 0);
419 assert_eq!(placement.end, -3);
420 }
421
422 #[test]
423 fn test_grid_placement_from_to() {
424 let placement = GridPlacement::from_to(2, 5);
425 assert_eq!(placement.start, 2);
426 assert_eq!(placement.end, 5);
427 }
428
429 #[test]
431 fn test_flex_direction_default() {
432 assert_eq!(FlexDirection::default(), FlexDirection::Row);
433 }
434
435 #[test]
436 fn test_flex_direction_variants() {
437 assert_eq!(FlexDirection::Row, FlexDirection::Row);
438 assert_eq!(FlexDirection::Column, FlexDirection::Column);
439 }
440
441 #[test]
443 fn test_justify_content_default() {
444 assert_eq!(JustifyContent::default(), JustifyContent::Start);
445 }
446
447 #[test]
448 fn test_justify_content_variants() {
449 assert_eq!(JustifyContent::Start, JustifyContent::Start);
450 assert_eq!(JustifyContent::Center, JustifyContent::Center);
451 assert_eq!(JustifyContent::End, JustifyContent::End);
452 assert_eq!(JustifyContent::SpaceBetween, JustifyContent::SpaceBetween);
453 assert_eq!(JustifyContent::SpaceAround, JustifyContent::SpaceAround);
454 }
455
456 #[test]
458 fn test_align_items_default() {
459 assert_eq!(AlignItems::default(), AlignItems::Start);
460 }
461
462 #[test]
463 fn test_align_items_variants() {
464 assert_eq!(AlignItems::Start, AlignItems::Start);
465 assert_eq!(AlignItems::Center, AlignItems::Center);
466 assert_eq!(AlignItems::End, AlignItems::End);
467 assert_eq!(AlignItems::Stretch, AlignItems::Stretch);
468 }
469
470 #[test]
472 fn test_spacing_default() {
473 let spacing = Spacing::default();
474 assert_eq!(spacing.top, 0);
475 assert_eq!(spacing.right, 0);
476 assert_eq!(spacing.bottom, 0);
477 assert_eq!(spacing.left, 0);
478 }
479
480 #[test]
481 fn test_spacing_all() {
482 let spacing = Spacing::all(10);
483 assert_eq!(spacing.top, 10);
484 assert_eq!(spacing.right, 10);
485 assert_eq!(spacing.bottom, 10);
486 assert_eq!(spacing.left, 10);
487 }
488
489 #[test]
490 fn test_spacing_vertical() {
491 let spacing = Spacing::vertical(10);
492 assert_eq!(spacing.top, 10);
493 assert_eq!(spacing.right, 0);
494 assert_eq!(spacing.bottom, 10);
495 assert_eq!(spacing.left, 0);
496 }
497
498 #[test]
499 fn test_spacing_horizontal() {
500 let spacing = Spacing::horizontal(10);
501 assert_eq!(spacing.top, 0);
502 assert_eq!(spacing.right, 10);
503 assert_eq!(spacing.bottom, 0);
504 assert_eq!(spacing.left, 10);
505 }
506
507 #[test]
508 fn test_spacing_new() {
509 let spacing = Spacing::new(10, 20, 30, 40);
510 assert_eq!(spacing.top, 10);
511 assert_eq!(spacing.right, 20);
512 assert_eq!(spacing.bottom, 30);
513 assert_eq!(spacing.left, 40);
514 }
515
516 #[test]
518 fn test_size_default() {
519 assert_eq!(Size::default(), Size::Auto);
520 }
521
522 #[test]
523 fn test_size_auto() {
524 assert_eq!(Size::Auto, Size::Auto);
525 }
526
527 #[test]
528 fn test_size_fixed() {
529 let size = Size::Fixed(100);
530 assert_eq!(size, Size::Fixed(100));
531 }
532
533 #[test]
534 fn test_size_percent() {
535 let size = Size::Percent(50.0);
536 assert_eq!(size, Size::Percent(50.0));
537 }
538
539 #[test]
541 fn test_border_style_default() {
542 assert_eq!(BorderStyle::default(), BorderStyle::None);
543 }
544
545 #[test]
546 fn test_border_style_variants() {
547 assert_eq!(BorderStyle::None, BorderStyle::None);
548 assert_eq!(BorderStyle::Solid, BorderStyle::Solid);
549 assert_eq!(BorderStyle::Dashed, BorderStyle::Dashed);
550 assert_eq!(BorderStyle::Double, BorderStyle::Double);
551 assert_eq!(BorderStyle::Rounded, BorderStyle::Rounded);
552 }
553
554 #[test]
556 fn test_color_default() {
557 let color = Color::default();
558 assert_eq!(color.r, 0);
559 assert_eq!(color.g, 0);
560 assert_eq!(color.b, 0);
561 assert_eq!(color.a, 0);
562 }
563
564 #[test]
565 fn test_color_partial_eq() {
566 let color1 = Color::rgb(255, 0, 0);
567 let color2 = Color::rgb(255, 0, 0);
568 assert_eq!(color1, color2);
569 }
570
571 #[test]
572 fn test_color_partial_ne() {
573 let color1 = Color::rgb(255, 0, 0);
574 let color2 = Color::rgb(0, 255, 0);
575 assert_ne!(color1, color2);
576 }
577
578 #[test]
579 fn test_color_copy_trait() {
580 let color1 = Color::rgb(255, 0, 0);
581 let color2 = color1;
582 assert_eq!(color1.r, 255);
583 assert_eq!(color2.r, 255);
584 }
585}