1mod color;
7mod theme;
8pub use color::{Color, ColorDepth};
9pub use theme::{Theme, ThemeBuilder};
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
16pub enum Breakpoint {
17 Xs,
19 Sm,
21 Md,
23 Lg,
25 Xl,
27}
28
29#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
34#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
35pub enum Border {
36 Single,
38 Double,
40 Rounded,
42 Thick,
44 Dashed,
46 DashedThick,
48}
49
50#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
55pub struct BorderChars {
56 pub tl: char,
58 pub tr: char,
60 pub bl: char,
62 pub br: char,
64 pub h: char,
66 pub v: char,
68}
69
70#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
72#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
73pub struct BorderSides {
74 pub top: bool,
76 pub right: bool,
78 pub bottom: bool,
80 pub left: bool,
82}
83
84impl BorderSides {
85 pub const fn all() -> Self {
87 Self {
88 top: true,
89 right: true,
90 bottom: true,
91 left: true,
92 }
93 }
94
95 pub const fn none() -> Self {
97 Self {
98 top: false,
99 right: false,
100 bottom: false,
101 left: false,
102 }
103 }
104
105 pub const fn horizontal() -> Self {
107 Self {
108 top: true,
109 right: false,
110 bottom: true,
111 left: false,
112 }
113 }
114
115 pub const fn vertical() -> Self {
117 Self {
118 top: false,
119 right: true,
120 bottom: false,
121 left: true,
122 }
123 }
124
125 pub fn has_horizontal(&self) -> bool {
127 self.top || self.bottom
128 }
129
130 pub fn has_vertical(&self) -> bool {
132 self.left || self.right
133 }
134}
135
136impl Default for BorderSides {
137 fn default() -> Self {
138 Self::all()
139 }
140}
141
142impl Border {
143 pub const fn chars(self) -> BorderChars {
145 match self {
146 Self::Single => BorderChars {
147 tl: '┌',
148 tr: '┐',
149 bl: '└',
150 br: '┘',
151 h: '─',
152 v: '│',
153 },
154 Self::Double => BorderChars {
155 tl: '╔',
156 tr: '╗',
157 bl: '╚',
158 br: '╝',
159 h: '═',
160 v: '║',
161 },
162 Self::Rounded => BorderChars {
163 tl: '╭',
164 tr: '╮',
165 bl: '╰',
166 br: '╯',
167 h: '─',
168 v: '│',
169 },
170 Self::Thick => BorderChars {
171 tl: '┏',
172 tr: '┓',
173 bl: '┗',
174 br: '┛',
175 h: '━',
176 v: '┃',
177 },
178 Self::Dashed => BorderChars {
179 tl: '┌',
180 tr: '┐',
181 bl: '└',
182 br: '┘',
183 h: '┄',
184 v: '┆',
185 },
186 Self::DashedThick => BorderChars {
187 tl: '┏',
188 tr: '┓',
189 bl: '┗',
190 br: '┛',
191 h: '┅',
192 v: '┇',
193 },
194 }
195 }
196}
197
198#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
203#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
204pub struct Padding {
205 pub top: u32,
207 pub right: u32,
209 pub bottom: u32,
211 pub left: u32,
213}
214
215impl Padding {
216 pub const fn all(v: u32) -> Self {
218 Self::new(v, v, v, v)
219 }
220
221 pub const fn xy(x: u32, y: u32) -> Self {
223 Self::new(y, x, y, x)
224 }
225
226 pub const fn new(top: u32, right: u32, bottom: u32, left: u32) -> Self {
228 Self {
229 top,
230 right,
231 bottom,
232 left,
233 }
234 }
235
236 pub const fn horizontal(self) -> u32 {
238 self.left + self.right
239 }
240
241 pub const fn vertical(self) -> u32 {
243 self.top + self.bottom
244 }
245}
246
247#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
252#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
253pub struct Margin {
254 pub top: u32,
256 pub right: u32,
258 pub bottom: u32,
260 pub left: u32,
262}
263
264impl Margin {
265 pub const fn all(v: u32) -> Self {
267 Self::new(v, v, v, v)
268 }
269
270 pub const fn xy(x: u32, y: u32) -> Self {
272 Self::new(y, x, y, x)
273 }
274
275 pub const fn new(top: u32, right: u32, bottom: u32, left: u32) -> Self {
277 Self {
278 top,
279 right,
280 bottom,
281 left,
282 }
283 }
284
285 pub const fn horizontal(self) -> u32 {
287 self.left + self.right
288 }
289
290 pub const fn vertical(self) -> u32 {
292 self.top + self.bottom
293 }
294}
295
296#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
309#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
310#[must_use = "configure constraints using the returned value"]
311pub struct Constraints {
312 pub min_width: Option<u32>,
314 pub max_width: Option<u32>,
316 pub min_height: Option<u32>,
318 pub max_height: Option<u32>,
320 pub width_pct: Option<u8>,
322 pub height_pct: Option<u8>,
324}
325
326impl Constraints {
327 pub const fn min_w(mut self, min_width: u32) -> Self {
329 self.min_width = Some(min_width);
330 self
331 }
332
333 pub const fn max_w(mut self, max_width: u32) -> Self {
335 self.max_width = Some(max_width);
336 self
337 }
338
339 pub const fn min_h(mut self, min_height: u32) -> Self {
341 self.min_height = Some(min_height);
342 self
343 }
344
345 pub const fn max_h(mut self, max_height: u32) -> Self {
347 self.max_height = Some(max_height);
348 self
349 }
350
351 pub const fn w_pct(mut self, pct: u8) -> Self {
353 self.width_pct = Some(pct);
354 self
355 }
356
357 pub const fn h_pct(mut self, pct: u8) -> Self {
359 self.height_pct = Some(pct);
360 self
361 }
362}
363
364#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
370#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
371pub enum Align {
372 #[default]
374 Start,
375 Center,
377 End,
379}
380
381#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
390#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
391pub enum Justify {
392 #[default]
394 Start,
395 Center,
397 End,
399 SpaceBetween,
401 SpaceAround,
403 SpaceEvenly,
405}
406
407#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
412#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
413#[cfg_attr(feature = "serde", serde(transparent))]
414pub struct Modifiers(pub u8);
415
416impl Modifiers {
417 pub const NONE: Self = Self(0);
419 pub const BOLD: Self = Self(1 << 0);
421 pub const DIM: Self = Self(1 << 1);
423 pub const ITALIC: Self = Self(1 << 2);
425 pub const UNDERLINE: Self = Self(1 << 3);
427 pub const REVERSED: Self = Self(1 << 4);
429 pub const STRIKETHROUGH: Self = Self(1 << 5);
431
432 #[inline]
434 pub fn contains(self, other: Self) -> bool {
435 (self.0 & other.0) == other.0
436 }
437
438 #[inline]
440 pub fn insert(&mut self, other: Self) {
441 self.0 |= other.0;
442 }
443
444 #[inline]
446 pub fn is_empty(self) -> bool {
447 self.0 == 0
448 }
449}
450
451impl std::ops::BitOr for Modifiers {
452 type Output = Self;
453 #[inline]
454 fn bitor(self, rhs: Self) -> Self {
455 Self(self.0 | rhs.0)
456 }
457}
458
459impl std::ops::BitOrAssign for Modifiers {
460 #[inline]
461 fn bitor_assign(&mut self, rhs: Self) {
462 self.0 |= rhs.0;
463 }
464}
465
466#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
480#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
481#[must_use = "build and pass the returned Style value"]
482pub struct Style {
483 pub fg: Option<Color>,
485 pub bg: Option<Color>,
487 pub modifiers: Modifiers,
489}
490
491impl Style {
492 pub const fn new() -> Self {
494 Self {
495 fg: None,
496 bg: None,
497 modifiers: Modifiers::NONE,
498 }
499 }
500
501 pub const fn fg(mut self, color: Color) -> Self {
503 self.fg = Some(color);
504 self
505 }
506
507 pub const fn bg(mut self, color: Color) -> Self {
509 self.bg = Some(color);
510 self
511 }
512
513 pub fn bold(mut self) -> Self {
515 self.modifiers |= Modifiers::BOLD;
516 self
517 }
518
519 pub fn dim(mut self) -> Self {
521 self.modifiers |= Modifiers::DIM;
522 self
523 }
524
525 pub fn italic(mut self) -> Self {
527 self.modifiers |= Modifiers::ITALIC;
528 self
529 }
530
531 pub fn underline(mut self) -> Self {
533 self.modifiers |= Modifiers::UNDERLINE;
534 self
535 }
536
537 pub fn reversed(mut self) -> Self {
539 self.modifiers |= Modifiers::REVERSED;
540 self
541 }
542
543 pub fn strikethrough(mut self) -> Self {
545 self.modifiers |= Modifiers::STRIKETHROUGH;
546 self
547 }
548}
549
550#[derive(Debug, Clone, Copy, Default)]
574pub struct ContainerStyle {
575 pub border: Option<Border>,
577 pub border_sides: Option<BorderSides>,
579 pub border_style: Option<Style>,
581 pub bg: Option<Color>,
583 pub text_color: Option<Color>,
585 pub dark_bg: Option<Color>,
587 pub dark_border_style: Option<Style>,
589 pub padding: Option<Padding>,
591 pub margin: Option<Margin>,
593 pub gap: Option<u32>,
595 pub row_gap: Option<u32>,
597 pub col_gap: Option<u32>,
599 pub grow: Option<u16>,
601 pub align: Option<Align>,
603 pub align_self: Option<Align>,
605 pub justify: Option<Justify>,
607 pub w: Option<u32>,
609 pub h: Option<u32>,
611 pub min_w: Option<u32>,
613 pub max_w: Option<u32>,
615 pub min_h: Option<u32>,
617 pub max_h: Option<u32>,
619 pub w_pct: Option<u8>,
621 pub h_pct: Option<u8>,
623}
624
625impl ContainerStyle {
626 pub const fn new() -> Self {
628 Self {
629 border: None,
630 border_sides: None,
631 border_style: None,
632 bg: None,
633 text_color: None,
634 dark_bg: None,
635 dark_border_style: None,
636 padding: None,
637 margin: None,
638 gap: None,
639 row_gap: None,
640 col_gap: None,
641 grow: None,
642 align: None,
643 align_self: None,
644 justify: None,
645 w: None,
646 h: None,
647 min_w: None,
648 max_w: None,
649 min_h: None,
650 max_h: None,
651 w_pct: None,
652 h_pct: None,
653 }
654 }
655
656 pub const fn border(mut self, border: Border) -> Self {
658 self.border = Some(border);
659 self
660 }
661
662 pub const fn border_sides(mut self, sides: BorderSides) -> Self {
664 self.border_sides = Some(sides);
665 self
666 }
667
668 pub const fn bg(mut self, color: Color) -> Self {
670 self.bg = Some(color);
671 self
672 }
673
674 pub const fn text_color(mut self, color: Color) -> Self {
676 self.text_color = Some(color);
677 self
678 }
679
680 pub const fn dark_bg(mut self, color: Color) -> Self {
682 self.dark_bg = Some(color);
683 self
684 }
685
686 pub const fn p(mut self, value: u32) -> Self {
688 self.padding = Some(Padding {
689 top: value,
690 bottom: value,
691 left: value,
692 right: value,
693 });
694 self
695 }
696
697 pub const fn px(mut self, value: u32) -> Self {
699 let p = match self.padding {
700 Some(p) => Padding {
701 left: value,
702 right: value,
703 ..p
704 },
705 None => Padding {
706 top: 0,
707 bottom: 0,
708 left: value,
709 right: value,
710 },
711 };
712 self.padding = Some(p);
713 self
714 }
715
716 pub const fn py(mut self, value: u32) -> Self {
718 let p = match self.padding {
719 Some(p) => Padding {
720 top: value,
721 bottom: value,
722 ..p
723 },
724 None => Padding {
725 top: value,
726 bottom: value,
727 left: 0,
728 right: 0,
729 },
730 };
731 self.padding = Some(p);
732 self
733 }
734
735 pub const fn m(mut self, value: u32) -> Self {
737 self.margin = Some(Margin {
738 top: value,
739 bottom: value,
740 left: value,
741 right: value,
742 });
743 self
744 }
745
746 pub const fn gap(mut self, value: u32) -> Self {
748 self.gap = Some(value);
749 self
750 }
751
752 pub const fn row_gap(mut self, value: u32) -> Self {
754 self.row_gap = Some(value);
755 self
756 }
757
758 pub const fn col_gap(mut self, value: u32) -> Self {
760 self.col_gap = Some(value);
761 self
762 }
763
764 pub const fn grow(mut self, value: u16) -> Self {
766 self.grow = Some(value);
767 self
768 }
769
770 pub const fn w(mut self, value: u32) -> Self {
772 self.w = Some(value);
773 self
774 }
775
776 pub const fn h(mut self, value: u32) -> Self {
778 self.h = Some(value);
779 self
780 }
781
782 pub const fn min_w(mut self, value: u32) -> Self {
784 self.min_w = Some(value);
785 self
786 }
787
788 pub const fn max_w(mut self, value: u32) -> Self {
790 self.max_w = Some(value);
791 self
792 }
793
794 pub const fn align(mut self, value: Align) -> Self {
796 self.align = Some(value);
797 self
798 }
799
800 pub const fn align_self(mut self, value: Align) -> Self {
802 self.align_self = Some(value);
803 self
804 }
805
806 pub const fn justify(mut self, value: Justify) -> Self {
808 self.justify = Some(value);
809 self
810 }
811
812 pub const fn min_h(mut self, value: u32) -> Self {
814 self.min_h = Some(value);
815 self
816 }
817
818 pub const fn max_h(mut self, value: u32) -> Self {
820 self.max_h = Some(value);
821 self
822 }
823
824 pub const fn w_pct(mut self, value: u8) -> Self {
826 self.w_pct = Some(value);
827 self
828 }
829
830 pub const fn h_pct(mut self, value: u8) -> Self {
832 self.h_pct = Some(value);
833 self
834 }
835}
836
837#[derive(Debug, Clone, Copy, Default)]
838#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
839pub struct WidgetColors {
841 pub fg: Option<Color>,
843 pub bg: Option<Color>,
845 pub border: Option<Color>,
847 pub accent: Option<Color>,
849}
850
851impl WidgetColors {
852 pub const fn new() -> Self {
854 Self {
855 fg: None,
856 bg: None,
857 border: None,
858 accent: None,
859 }
860 }
861
862 pub const fn fg(mut self, color: Color) -> Self {
864 self.fg = Some(color);
865 self
866 }
867
868 pub const fn bg(mut self, color: Color) -> Self {
870 self.bg = Some(color);
871 self
872 }
873
874 pub const fn border(mut self, color: Color) -> Self {
876 self.border = Some(color);
877 self
878 }
879
880 pub const fn accent(mut self, color: Color) -> Self {
882 self.accent = Some(color);
883 self
884 }
885}
886
887#[cfg(test)]
888mod tests {
889 use super::*;
890
891 #[test]
892 fn style_new_is_default() {
893 let style = Style::new();
894 assert_eq!(style.fg, None);
895 assert_eq!(style.bg, None);
896 assert_eq!(style.modifiers, Modifiers::NONE);
897 assert_eq!(style, Style::default());
898 }
899
900 #[test]
901 fn style_bold_and_fg_set_expected_fields() {
902 let style = Style::new().bold().fg(Color::Red);
903 assert_eq!(style.fg, Some(Color::Red));
904 assert_eq!(style.bg, None);
905 assert!(style.modifiers.contains(Modifiers::BOLD));
906 }
907
908 #[test]
909 fn style_multiple_modifiers_accumulate() {
910 let style = Style::new().italic().underline().dim();
911 assert!(style.modifiers.contains(Modifiers::ITALIC));
912 assert!(style.modifiers.contains(Modifiers::UNDERLINE));
913 assert!(style.modifiers.contains(Modifiers::DIM));
914 }
915
916 #[test]
917 fn style_repeated_fg_overrides_previous_color() {
918 let style = Style::new().fg(Color::Blue).fg(Color::Green);
919 assert_eq!(style.fg, Some(Color::Green));
920 }
921
922 #[test]
923 fn style_repeated_bg_overrides_previous_color() {
924 let style = Style::new().bg(Color::Blue).bg(Color::Green);
925 assert_eq!(style.bg, Some(Color::Green));
926 }
927
928 #[test]
929 fn style_override_preserves_existing_modifiers() {
930 let style = Style::new().bold().fg(Color::Red).fg(Color::Yellow);
931 assert_eq!(style.fg, Some(Color::Yellow));
932 assert!(style.modifiers.contains(Modifiers::BOLD));
933 }
934
935 #[test]
936 fn padding_all_sets_all_sides() {
937 let p = Padding::all(3);
938 assert_eq!(p.top, 3);
939 assert_eq!(p.right, 3);
940 assert_eq!(p.bottom, 3);
941 assert_eq!(p.left, 3);
942 }
943
944 #[test]
945 fn padding_xy_sets_axis_values() {
946 let p = Padding::xy(4, 2);
947 assert_eq!(p.top, 2);
948 assert_eq!(p.bottom, 2);
949 assert_eq!(p.left, 4);
950 assert_eq!(p.right, 4);
951 }
952
953 #[test]
954 fn padding_new_and_totals_are_correct() {
955 let p = Padding::new(1, 2, 3, 4);
956 assert_eq!(p.top, 1);
957 assert_eq!(p.right, 2);
958 assert_eq!(p.bottom, 3);
959 assert_eq!(p.left, 4);
960 assert_eq!(p.horizontal(), 6);
961 assert_eq!(p.vertical(), 4);
962 }
963
964 #[test]
965 fn margin_all_and_xy_are_correct() {
966 let all = Margin::all(5);
967 assert_eq!(all, Margin::new(5, 5, 5, 5));
968
969 let xy = Margin::xy(7, 1);
970 assert_eq!(xy.top, 1);
971 assert_eq!(xy.bottom, 1);
972 assert_eq!(xy.left, 7);
973 assert_eq!(xy.right, 7);
974 }
975
976 #[test]
977 fn margin_new_and_totals_are_correct() {
978 let m = Margin::new(2, 4, 6, 8);
979 assert_eq!(m.horizontal(), 12);
980 assert_eq!(m.vertical(), 8);
981 }
982
983 #[test]
984 fn constraints_min_max_builder_sets_values() {
985 let c = Constraints::default()
986 .min_w(10)
987 .max_w(40)
988 .min_h(5)
989 .max_h(20);
990 assert_eq!(c.min_width, Some(10));
991 assert_eq!(c.max_width, Some(40));
992 assert_eq!(c.min_height, Some(5));
993 assert_eq!(c.max_height, Some(20));
994 }
995
996 #[test]
997 fn constraints_percentage_builder_sets_values() {
998 let c = Constraints::default().w_pct(50).h_pct(80);
999 assert_eq!(c.width_pct, Some(50));
1000 assert_eq!(c.height_pct, Some(80));
1001 }
1002
1003 #[test]
1004 fn border_sides_all_has_both_axes() {
1005 let sides = BorderSides::all();
1006 assert!(sides.top && sides.right && sides.bottom && sides.left);
1007 assert!(sides.has_horizontal());
1008 assert!(sides.has_vertical());
1009 }
1010
1011 #[test]
1012 fn border_sides_none_has_no_axes() {
1013 let sides = BorderSides::none();
1014 assert!(!sides.top && !sides.right && !sides.bottom && !sides.left);
1015 assert!(!sides.has_horizontal());
1016 assert!(!sides.has_vertical());
1017 }
1018
1019 #[test]
1020 fn border_sides_horizontal_only() {
1021 let sides = BorderSides::horizontal();
1022 assert!(sides.top);
1023 assert!(sides.bottom);
1024 assert!(!sides.left);
1025 assert!(!sides.right);
1026 assert!(sides.has_horizontal());
1027 assert!(!sides.has_vertical());
1028 }
1029
1030 #[test]
1031 fn border_sides_vertical_only() {
1032 let sides = BorderSides::vertical();
1033 assert!(!sides.top);
1034 assert!(!sides.bottom);
1035 assert!(sides.left);
1036 assert!(sides.right);
1037 assert!(!sides.has_horizontal());
1038 assert!(sides.has_vertical());
1039 }
1040
1041 #[test]
1042 fn container_style_new_is_empty() {
1043 let s = ContainerStyle::new();
1044 assert_eq!(s.border, None);
1045 assert_eq!(s.bg, None);
1046 assert_eq!(s.padding, None);
1047 assert_eq!(s.margin, None);
1048 assert_eq!(s.gap, None);
1049 assert_eq!(s.align, None);
1050 assert_eq!(s.justify, None);
1051 }
1052
1053 #[test]
1054 fn container_style_const_construction_and_fields() {
1055 const CARD: ContainerStyle = ContainerStyle::new()
1056 .border(Border::Rounded)
1057 .border_sides(BorderSides::horizontal())
1058 .p(2)
1059 .m(1)
1060 .gap(3)
1061 .align(Align::Center)
1062 .justify(Justify::SpaceBetween)
1063 .w(60)
1064 .h(20);
1065
1066 assert_eq!(CARD.border, Some(Border::Rounded));
1067 assert_eq!(CARD.border_sides, Some(BorderSides::horizontal()));
1068 assert_eq!(CARD.padding, Some(Padding::all(2)));
1069 assert_eq!(CARD.margin, Some(Margin::all(1)));
1070 assert_eq!(CARD.gap, Some(3));
1071 assert_eq!(CARD.align, Some(Align::Center));
1072 assert_eq!(CARD.justify, Some(Justify::SpaceBetween));
1073 assert_eq!(CARD.w, Some(60));
1074 assert_eq!(CARD.h, Some(20));
1075 }
1076
1077 #[test]
1078 fn widget_colors_new_is_empty() {
1079 let colors = WidgetColors::new();
1080 assert_eq!(colors.fg, None);
1081 assert_eq!(colors.bg, None);
1082 assert_eq!(colors.border, None);
1083 assert_eq!(colors.accent, None);
1084
1085 let defaults = WidgetColors::default();
1086 assert_eq!(defaults.fg, None);
1087 assert_eq!(defaults.bg, None);
1088 assert_eq!(defaults.border, None);
1089 assert_eq!(defaults.accent, None);
1090 }
1091
1092 #[test]
1093 fn widget_colors_builder_sets_all_fields() {
1094 let colors = WidgetColors::new()
1095 .fg(Color::White)
1096 .bg(Color::Black)
1097 .border(Color::Cyan)
1098 .accent(Color::Yellow);
1099
1100 assert_eq!(colors.fg, Some(Color::White));
1101 assert_eq!(colors.bg, Some(Color::Black));
1102 assert_eq!(colors.border, Some(Color::Cyan));
1103 assert_eq!(colors.accent, Some(Color::Yellow));
1104 }
1105
1106 #[test]
1107 fn align_default_is_start() {
1108 assert_eq!(Align::default(), Align::Start);
1109 }
1110
1111 #[test]
1112 fn justify_default_is_start() {
1113 assert_eq!(Justify::default(), Justify::Start);
1114 }
1115
1116 #[test]
1117 fn align_and_justify_variants_are_distinct() {
1118 assert_ne!(Align::Start, Align::Center);
1119 assert_ne!(Align::Center, Align::End);
1120
1121 assert_ne!(Justify::Start, Justify::Center);
1122 assert_ne!(Justify::Center, Justify::End);
1123 assert_ne!(Justify::SpaceBetween, Justify::SpaceAround);
1124 assert_ne!(Justify::SpaceAround, Justify::SpaceEvenly);
1125 }
1126}