1mod alignment;
3mod available_space;
4mod compact_length;
5mod dimension;
6
7#[cfg(feature = "block_layout")]
8mod block;
9#[cfg(feature = "flexbox")]
10mod flex;
11#[cfg(feature = "float_layout")]
12mod float;
13#[cfg(feature = "grid")]
14mod grid;
15
16pub use self::alignment::{
17 AlignContent, AlignContentKeyword, AlignItems, AlignItemsKeyword, AlignSelf, AlignmentSafety, JustifyContent,
18 JustifyItems, JustifySelf,
19};
20pub use self::available_space::AvailableSpace;
21pub use self::compact_length::CompactLength;
22pub use self::dimension::{Dimension, LengthPercentage, LengthPercentageAuto};
23use crate::sys::DefaultCheapStr;
24
25#[cfg(feature = "block_layout")]
26pub use self::block::{BlockContainerStyle, BlockItemStyle, TextAlign};
27#[cfg(feature = "flexbox")]
28pub use self::flex::{FlexDirection, FlexWrap, FlexboxContainerStyle, FlexboxItemStyle};
29#[cfg(feature = "float_layout")]
30pub use self::float::{Clear, Float, FloatDirection};
31#[cfg(feature = "grid")]
32pub use self::grid::{
33 GenericGridPlacement, GenericGridTemplateComponent, GenericRepetition, GridAutoFlow, GridAutoTracks,
34 GridContainerStyle, GridItemStyle, GridPlacement, GridTemplateComponent, GridTemplateRepetition,
35 GridTemplateTracks, MaxTrackSizingFunction, MinTrackSizingFunction, RepetitionCount, TrackSizingFunction,
36};
37#[cfg(feature = "grid")]
38pub(crate) use self::grid::{GridAreaAxis, GridAreaEnd};
39#[cfg(feature = "grid")]
40pub use self::grid::{GridTemplateArea, NamedGridLine, TemplateLineNames};
41#[cfg(feature = "grid")]
42pub(crate) use self::grid::{NonNamedGridPlacement, OriginZeroGridPlacement};
43
44use crate::geometry::{Point, Rect, Size};
45use crate::style_helpers::TaffyAuto as _;
46use core::fmt::Debug;
47
48#[cfg(feature = "grid")]
49use crate::geometry::Line;
50#[cfg(feature = "serde")]
51use crate::style_helpers;
52#[cfg(feature = "grid")]
53use crate::util::sys::GridTrackVec;
54
55use crate::sys::String;
56
57#[cfg(any(feature = "alloc", feature = "std"))]
60pub trait CheapCloneStr:
61 AsRef<str> + for<'a> From<&'a str> + From<String> + PartialEq + Eq + Clone + Default + Debug + 'static
62{
63}
64#[cfg(any(feature = "alloc", feature = "std"))]
65impl<T> CheapCloneStr for T where
66 T: AsRef<str> + for<'a> From<&'a str> + From<String> + PartialEq + Eq + Clone + Default + Debug + 'static
67{
68}
69
70#[cfg(not(any(feature = "alloc", feature = "std")))]
73pub trait CheapCloneStr {}
74#[cfg(not(any(feature = "alloc", feature = "std")))]
75impl<T> CheapCloneStr for T {}
76
77pub trait CoreStyle {
83 type CustomIdent: CheapCloneStr;
85
86 #[inline(always)]
88 fn box_generation_mode(&self) -> BoxGenerationMode {
89 BoxGenerationMode::DEFAULT
90 }
91 #[inline(always)]
93 fn is_block(&self) -> bool {
94 false
95 }
96 #[inline(always)]
99 fn is_compressible_replaced(&self) -> bool {
100 false
101 }
102 #[inline(always)]
104 fn box_sizing(&self) -> BoxSizing {
105 BoxSizing::BorderBox
106 }
107
108 #[inline(always)]
110 fn direction(&self) -> Direction {
111 Direction::Ltr
112 }
113
114 #[inline(always)]
117 fn overflow(&self) -> Point<Overflow> {
118 Style::<Self::CustomIdent>::DEFAULT.overflow
119 }
120 #[inline(always)]
122 fn scrollbar_width(&self) -> f32 {
123 0.0
124 }
125
126 #[inline(always)]
129 fn position(&self) -> Position {
130 Style::<Self::CustomIdent>::DEFAULT.position
131 }
132 #[inline(always)]
134 fn inset(&self) -> Rect<LengthPercentageAuto> {
135 Style::<Self::CustomIdent>::DEFAULT.inset
136 }
137
138 #[inline(always)]
141 fn size(&self) -> Size<Dimension> {
142 Style::<Self::CustomIdent>::DEFAULT.size
143 }
144 #[inline(always)]
146 fn min_size(&self) -> Size<Dimension> {
147 Style::<Self::CustomIdent>::DEFAULT.min_size
148 }
149 #[inline(always)]
151 fn max_size(&self) -> Size<Dimension> {
152 Style::<Self::CustomIdent>::DEFAULT.max_size
153 }
154 #[inline(always)]
157 fn aspect_ratio(&self) -> Option<f32> {
158 Style::<Self::CustomIdent>::DEFAULT.aspect_ratio
159 }
160
161 #[inline(always)]
164 fn margin(&self) -> Rect<LengthPercentageAuto> {
165 Style::<Self::CustomIdent>::DEFAULT.margin
166 }
167 #[inline(always)]
169 fn padding(&self) -> Rect<LengthPercentage> {
170 Style::<Self::CustomIdent>::DEFAULT.padding
171 }
172 #[inline(always)]
174 fn border(&self) -> Rect<LengthPercentage> {
175 Style::<Self::CustomIdent>::DEFAULT.border
176 }
177}
178
179#[derive(Copy, Clone, PartialEq, Eq, Debug)]
183#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
184pub enum Display {
185 #[cfg(feature = "block_layout")]
187 Block,
188 #[cfg(feature = "flexbox")]
190 Flex,
191 #[cfg(feature = "grid")]
193 Grid,
194 None,
196}
197
198impl Display {
199 #[cfg(feature = "flexbox")]
201 pub const DEFAULT: Display = Display::Flex;
202
203 #[cfg(all(feature = "grid", not(feature = "flexbox")))]
205 pub const DEFAULT: Display = Display::Grid;
206
207 #[cfg(all(feature = "block_layout", not(feature = "flexbox"), not(feature = "grid")))]
209 pub const DEFAULT: Display = Display::Block;
210
211 #[cfg(all(not(feature = "flexbox"), not(feature = "grid"), not(feature = "block_layout")))]
213 pub const DEFAULT: Display = Display::None;
214}
215
216impl Default for Display {
217 fn default() -> Self {
218 Self::DEFAULT
219 }
220}
221
222#[cfg(feature = "parse")]
223crate::util::parse::impl_parse_for_keyword_enum!(Display,
224 "none" => None,
225 #[cfg(feature = "flexbox")]
226 "flex" => Flex,
227 #[cfg(feature = "grid")]
228 "grid" => Grid,
229 #[cfg(feature = "block_layout")]
230 "block" => Block,
231);
232
233impl core::fmt::Display for Display {
234 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
235 match self {
236 Display::None => write!(f, "NONE"),
237 #[cfg(feature = "block_layout")]
238 Display::Block => write!(f, "BLOCK"),
239 #[cfg(feature = "flexbox")]
240 Display::Flex => write!(f, "FLEX"),
241 #[cfg(feature = "grid")]
242 Display::Grid => write!(f, "GRID"),
243 }
244 }
245}
246
247#[derive(Copy, Clone, PartialEq, Eq, Debug)]
250#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
251pub enum BoxGenerationMode {
252 Normal,
254 None,
256}
257
258impl BoxGenerationMode {
259 pub const DEFAULT: BoxGenerationMode = BoxGenerationMode::Normal;
261}
262
263impl Default for BoxGenerationMode {
264 fn default() -> Self {
265 Self::DEFAULT
266 }
267}
268
269#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)]
279#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
280pub enum Position {
281 #[default]
284 Relative,
285 Absolute,
291}
292
293#[cfg(feature = "parse")]
294crate::util::parse::impl_parse_for_keyword_enum!(Position,
295 "relative" => Relative,
296 "absolute" => Absolute,
297);
298
299#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)]
313#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
314pub enum BoxSizing {
315 #[default]
317 BorderBox,
318 ContentBox,
320}
321
322#[cfg(feature = "parse")]
323crate::util::parse::impl_parse_for_keyword_enum!(BoxSizing,
324 "border-box" => BorderBox,
325 "content-box" => ContentBox,
326);
327
328#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)]
342#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
343pub enum Overflow {
344 #[default]
347 Visible,
348 Clip,
351 Hidden,
354 Scroll,
358}
359
360impl Overflow {
361 #[inline(always)]
364 pub fn is_scroll_container(self) -> bool {
365 match self {
366 Self::Visible | Self::Clip => false,
367 Self::Hidden | Self::Scroll => true,
368 }
369 }
370
371 #[inline(always)]
374 pub(crate) fn maybe_into_automatic_min_size(self) -> Option<f32> {
375 match self.is_scroll_container() {
376 true => Some(0.0),
377 false => None,
378 }
379 }
380}
381
382#[cfg(feature = "parse")]
383crate::util::parse::impl_parse_for_keyword_enum!(Overflow,
384 "visible" => Visible,
385 "hidden" => Hidden,
386 "clip" => Clip,
387 "scroll" => Scroll,
388);
389
390#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)]
393#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
394pub enum Direction {
395 #[default]
396 Ltr,
398 Rtl,
400}
401
402impl Direction {
403 #[inline]
405 pub(crate) fn is_rtl(&self) -> bool {
406 matches!(self, Direction::Rtl)
407 }
408}
409
410#[cfg(feature = "parse")]
411crate::util::parse::impl_parse_for_keyword_enum!(Direction,
412 "ltr" => Ltr,
413 "rtl" => Rtl,
414);
415
416#[derive(Clone, PartialEq, Debug)]
431#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
432#[cfg_attr(feature = "serde", serde(default))]
433pub struct Style<S: CheapCloneStr = DefaultCheapStr> {
434 pub dummy: core::marker::PhantomData<S>,
437 pub display: Display,
439 pub item_is_table: bool,
442 pub item_is_replaced: bool,
445 pub box_sizing: BoxSizing,
447 pub direction: Direction,
449
450 pub overflow: Point<Overflow>,
453 pub scrollbar_width: f32,
455
456 #[cfg(feature = "float_layout")]
457 pub float: Float,
459 #[cfg(feature = "float_layout")]
460 pub clear: Clear,
462
463 pub position: Position,
466 #[cfg_attr(feature = "serde", serde(default = "style_helpers::auto"))]
468 pub inset: Rect<LengthPercentageAuto>,
469
470 #[cfg_attr(feature = "serde", serde(default = "style_helpers::auto"))]
473 pub size: Size<Dimension>,
474 #[cfg_attr(feature = "serde", serde(default = "style_helpers::auto"))]
476 pub min_size: Size<Dimension>,
477 #[cfg_attr(feature = "serde", serde(default = "style_helpers::auto"))]
479 pub max_size: Size<Dimension>,
480 pub aspect_ratio: Option<f32>,
484
485 #[cfg_attr(feature = "serde", serde(default = "style_helpers::zero"))]
488 pub margin: Rect<LengthPercentageAuto>,
489 #[cfg_attr(feature = "serde", serde(default = "style_helpers::zero"))]
491 pub padding: Rect<LengthPercentage>,
492 #[cfg_attr(feature = "serde", serde(default = "style_helpers::zero"))]
494 pub border: Rect<LengthPercentage>,
495
496 #[cfg(any(feature = "flexbox", feature = "grid"))]
499 pub align_items: Option<AlignItems>,
500 #[cfg(any(feature = "flexbox", feature = "grid"))]
503 pub align_self: Option<AlignSelf>,
504 #[cfg(feature = "grid")]
506 pub justify_items: Option<AlignItems>,
507 #[cfg(feature = "grid")]
510 pub justify_self: Option<AlignSelf>,
511 #[cfg(any(feature = "flexbox", feature = "grid", feature = "block_layout"))]
513 pub align_content: Option<AlignContent>,
514 #[cfg(any(feature = "flexbox", feature = "grid"))]
516 pub justify_content: Option<JustifyContent>,
517 #[cfg(any(feature = "flexbox", feature = "grid"))]
519 #[cfg_attr(feature = "serde", serde(default = "style_helpers::zero"))]
520 pub gap: Size<LengthPercentage>,
521
522 #[cfg(feature = "block_layout")]
525 pub text_align: TextAlign,
526
527 #[cfg(feature = "flexbox")]
530 pub flex_direction: FlexDirection,
531 #[cfg(feature = "flexbox")]
533 pub flex_wrap: FlexWrap,
534
535 #[cfg(feature = "flexbox")]
538 pub flex_basis: Dimension,
539 #[cfg(feature = "flexbox")]
543 pub flex_grow: f32,
544 #[cfg(feature = "flexbox")]
548 pub flex_shrink: f32,
549
550 #[cfg(feature = "grid")]
553 pub grid_template_rows: GridTrackVec<GridTemplateComponent<S>>,
554 #[cfg(feature = "grid")]
556 pub grid_template_columns: GridTrackVec<GridTemplateComponent<S>>,
557 #[cfg(feature = "grid")]
559 pub grid_auto_rows: GridTrackVec<TrackSizingFunction>,
560 #[cfg(feature = "grid")]
562 pub grid_auto_columns: GridTrackVec<TrackSizingFunction>,
563 #[cfg(feature = "grid")]
565 pub grid_auto_flow: GridAutoFlow,
566
567 #[cfg(feature = "grid")]
570 pub grid_template_areas: GridTrackVec<GridTemplateArea<S>>,
571 #[cfg(feature = "grid")]
573 pub grid_template_column_names: GridTrackVec<GridTrackVec<S>>,
574 #[cfg(feature = "grid")]
576 pub grid_template_row_names: GridTrackVec<GridTrackVec<S>>,
577
578 #[cfg(feature = "grid")]
581 pub grid_row: Line<GridPlacement<S>>,
582 #[cfg(feature = "grid")]
584 pub grid_column: Line<GridPlacement<S>>,
585}
586
587impl<S: CheapCloneStr> Style<S> {
588 pub const DEFAULT: Style<S> = Style {
590 dummy: core::marker::PhantomData,
591 display: Display::DEFAULT,
592 item_is_table: false,
593 item_is_replaced: false,
594 box_sizing: BoxSizing::BorderBox,
595 direction: Direction::Ltr,
596 overflow: Point { x: Overflow::Visible, y: Overflow::Visible },
597 scrollbar_width: 0.0,
598 #[cfg(feature = "float_layout")]
599 float: Float::None,
600 #[cfg(feature = "float_layout")]
601 clear: Clear::None,
602 position: Position::Relative,
603 inset: Rect::auto(),
604 margin: Rect::zero(),
605 padding: Rect::zero(),
606 border: Rect::zero(),
607 size: Size::auto(),
608 min_size: Size::auto(),
609 max_size: Size::auto(),
610 aspect_ratio: None,
611 #[cfg(any(feature = "flexbox", feature = "grid"))]
612 gap: Size::zero(),
613 #[cfg(any(feature = "flexbox", feature = "grid"))]
615 align_items: None,
616 #[cfg(any(feature = "flexbox", feature = "grid"))]
617 align_self: None,
618 #[cfg(feature = "grid")]
619 justify_items: None,
620 #[cfg(feature = "grid")]
621 justify_self: None,
622 #[cfg(any(feature = "flexbox", feature = "grid", feature = "block_layout"))]
623 align_content: None,
624 #[cfg(any(feature = "flexbox", feature = "grid"))]
625 justify_content: None,
626 #[cfg(feature = "block_layout")]
628 text_align: TextAlign::Auto,
629 #[cfg(feature = "flexbox")]
631 flex_direction: FlexDirection::Row,
632 #[cfg(feature = "flexbox")]
633 flex_wrap: FlexWrap::NoWrap,
634 #[cfg(feature = "flexbox")]
635 flex_grow: 0.0,
636 #[cfg(feature = "flexbox")]
637 flex_shrink: 1.0,
638 #[cfg(feature = "flexbox")]
639 flex_basis: Dimension::AUTO,
640 #[cfg(feature = "grid")]
642 grid_template_rows: GridTrackVec::new(),
643 #[cfg(feature = "grid")]
644 grid_template_columns: GridTrackVec::new(),
645 #[cfg(feature = "grid")]
646 grid_template_areas: GridTrackVec::new(),
647 #[cfg(feature = "grid")]
648 grid_template_column_names: GridTrackVec::new(),
649 #[cfg(feature = "grid")]
650 grid_template_row_names: GridTrackVec::new(),
651 #[cfg(feature = "grid")]
652 grid_auto_rows: GridTrackVec::new(),
653 #[cfg(feature = "grid")]
654 grid_auto_columns: GridTrackVec::new(),
655 #[cfg(feature = "grid")]
656 grid_auto_flow: GridAutoFlow::Row,
657 #[cfg(feature = "grid")]
658 grid_row: Line { start: GridPlacement::<S>::Auto, end: GridPlacement::<S>::Auto },
659 #[cfg(feature = "grid")]
660 grid_column: Line { start: GridPlacement::<S>::Auto, end: GridPlacement::<S>::Auto },
661 };
662}
663
664impl<S: CheapCloneStr> Default for Style<S> {
665 fn default() -> Self {
666 Style::DEFAULT
667 }
668}
669
670impl<S: CheapCloneStr> CoreStyle for Style<S> {
671 type CustomIdent = S;
672
673 #[inline(always)]
674 fn box_generation_mode(&self) -> BoxGenerationMode {
675 match self.display {
676 Display::None => BoxGenerationMode::None,
677 _ => BoxGenerationMode::Normal,
678 }
679 }
680 #[inline(always)]
681 #[cfg(feature = "block_layout")]
682 fn is_block(&self) -> bool {
683 matches!(self.display, Display::Block)
684 }
685 #[inline(always)]
686 fn is_compressible_replaced(&self) -> bool {
687 self.item_is_replaced
688 }
689 #[inline(always)]
690 fn box_sizing(&self) -> BoxSizing {
691 self.box_sizing
692 }
693 #[inline(always)]
694 fn direction(&self) -> Direction {
695 self.direction
696 }
697 #[inline(always)]
698 fn overflow(&self) -> Point<Overflow> {
699 self.overflow
700 }
701 #[inline(always)]
702 fn scrollbar_width(&self) -> f32 {
703 self.scrollbar_width
704 }
705 #[inline(always)]
706 fn position(&self) -> Position {
707 self.position
708 }
709 #[inline(always)]
710 fn inset(&self) -> Rect<LengthPercentageAuto> {
711 self.inset
712 }
713 #[inline(always)]
714 fn size(&self) -> Size<Dimension> {
715 self.size
716 }
717 #[inline(always)]
718 fn min_size(&self) -> Size<Dimension> {
719 self.min_size
720 }
721 #[inline(always)]
722 fn max_size(&self) -> Size<Dimension> {
723 self.max_size
724 }
725 #[inline(always)]
726 fn aspect_ratio(&self) -> Option<f32> {
727 self.aspect_ratio
728 }
729 #[inline(always)]
730 fn margin(&self) -> Rect<LengthPercentageAuto> {
731 self.margin
732 }
733 #[inline(always)]
734 fn padding(&self) -> Rect<LengthPercentage> {
735 self.padding
736 }
737 #[inline(always)]
738 fn border(&self) -> Rect<LengthPercentage> {
739 self.border
740 }
741}
742
743impl<T: CoreStyle> CoreStyle for &'_ T {
744 type CustomIdent = T::CustomIdent;
745
746 #[inline(always)]
747 fn box_generation_mode(&self) -> BoxGenerationMode {
748 (*self).box_generation_mode()
749 }
750 #[inline(always)]
751 fn is_block(&self) -> bool {
752 (*self).is_block()
753 }
754 #[inline(always)]
755 fn is_compressible_replaced(&self) -> bool {
756 (*self).is_compressible_replaced()
757 }
758 #[inline(always)]
759 fn box_sizing(&self) -> BoxSizing {
760 (*self).box_sizing()
761 }
762 #[inline(always)]
763 fn direction(&self) -> Direction {
764 (*self).direction()
765 }
766 #[inline(always)]
767 fn overflow(&self) -> Point<Overflow> {
768 (*self).overflow()
769 }
770 #[inline(always)]
771 fn scrollbar_width(&self) -> f32 {
772 (*self).scrollbar_width()
773 }
774 #[inline(always)]
775 fn position(&self) -> Position {
776 (*self).position()
777 }
778 #[inline(always)]
779 fn inset(&self) -> Rect<LengthPercentageAuto> {
780 (*self).inset()
781 }
782 #[inline(always)]
783 fn size(&self) -> Size<Dimension> {
784 (*self).size()
785 }
786 #[inline(always)]
787 fn min_size(&self) -> Size<Dimension> {
788 (*self).min_size()
789 }
790 #[inline(always)]
791 fn max_size(&self) -> Size<Dimension> {
792 (*self).max_size()
793 }
794 #[inline(always)]
795 fn aspect_ratio(&self) -> Option<f32> {
796 (*self).aspect_ratio()
797 }
798 #[inline(always)]
799 fn margin(&self) -> Rect<LengthPercentageAuto> {
800 (*self).margin()
801 }
802 #[inline(always)]
803 fn padding(&self) -> Rect<LengthPercentage> {
804 (*self).padding()
805 }
806 #[inline(always)]
807 fn border(&self) -> Rect<LengthPercentage> {
808 (*self).border()
809 }
810}
811
812#[cfg(feature = "block_layout")]
813impl<S: CheapCloneStr> BlockContainerStyle for Style<S> {
814 #[inline(always)]
815 fn text_align(&self) -> TextAlign {
816 self.text_align
817 }
818
819 #[inline(always)]
820 fn align_content(&self) -> Option<AlignContent> {
821 self.align_content
822 }
823}
824
825#[cfg(feature = "block_layout")]
826impl<T: BlockContainerStyle> BlockContainerStyle for &'_ T {
827 #[inline(always)]
828 fn text_align(&self) -> TextAlign {
829 (*self).text_align()
830 }
831
832 #[inline(always)]
833 fn align_content(&self) -> Option<AlignContent> {
834 (*self).align_content()
835 }
836}
837
838#[cfg(feature = "block_layout")]
839impl<S: CheapCloneStr> BlockItemStyle for Style<S> {
840 #[inline(always)]
841 fn is_table(&self) -> bool {
842 self.item_is_table
843 }
844
845 #[cfg(feature = "float_layout")]
846 #[inline(always)]
847 fn float(&self) -> Float {
848 self.float
849 }
850
851 #[cfg(feature = "float_layout")]
852 #[inline(always)]
853 fn clear(&self) -> Clear {
854 self.clear
855 }
856}
857
858#[cfg(feature = "block_layout")]
859impl<T: BlockItemStyle> BlockItemStyle for &'_ T {
860 #[inline(always)]
861 fn is_table(&self) -> bool {
862 (*self).is_table()
863 }
864
865 #[cfg(feature = "float_layout")]
866 #[inline(always)]
867 fn float(&self) -> Float {
868 (*self).float()
869 }
870
871 #[cfg(feature = "float_layout")]
872 #[inline(always)]
873 fn clear(&self) -> Clear {
874 (*self).clear()
875 }
876}
877
878#[cfg(feature = "flexbox")]
879impl<S: CheapCloneStr> FlexboxContainerStyle for Style<S> {
880 #[inline(always)]
881 fn flex_direction(&self) -> FlexDirection {
882 self.flex_direction
883 }
884 #[inline(always)]
885 fn flex_wrap(&self) -> FlexWrap {
886 self.flex_wrap
887 }
888 #[inline(always)]
889 fn gap(&self) -> Size<LengthPercentage> {
890 self.gap
891 }
892 #[inline(always)]
893 fn align_content(&self) -> Option<AlignContent> {
894 self.align_content
895 }
896 #[inline(always)]
897 fn align_items(&self) -> Option<AlignItems> {
898 self.align_items
899 }
900 #[inline(always)]
901 fn justify_content(&self) -> Option<JustifyContent> {
902 self.justify_content
903 }
904}
905
906#[cfg(feature = "flexbox")]
907impl<T: FlexboxContainerStyle> FlexboxContainerStyle for &'_ T {
908 #[inline(always)]
909 fn flex_direction(&self) -> FlexDirection {
910 (*self).flex_direction()
911 }
912 #[inline(always)]
913 fn flex_wrap(&self) -> FlexWrap {
914 (*self).flex_wrap()
915 }
916 #[inline(always)]
917 fn gap(&self) -> Size<LengthPercentage> {
918 (*self).gap()
919 }
920 #[inline(always)]
921 fn align_content(&self) -> Option<AlignContent> {
922 (*self).align_content()
923 }
924 #[inline(always)]
925 fn align_items(&self) -> Option<AlignItems> {
926 (*self).align_items()
927 }
928 #[inline(always)]
929 fn justify_content(&self) -> Option<JustifyContent> {
930 (*self).justify_content()
931 }
932}
933
934#[cfg(feature = "flexbox")]
935impl<S: CheapCloneStr> FlexboxItemStyle for Style<S> {
936 #[inline(always)]
937 fn flex_basis(&self) -> Dimension {
938 self.flex_basis
939 }
940 #[inline(always)]
941 fn flex_grow(&self) -> f32 {
942 self.flex_grow
943 }
944 #[inline(always)]
945 fn flex_shrink(&self) -> f32 {
946 self.flex_shrink
947 }
948 #[inline(always)]
949 fn align_self(&self) -> Option<AlignSelf> {
950 self.align_self
951 }
952}
953
954#[cfg(feature = "flexbox")]
955impl<T: FlexboxItemStyle> FlexboxItemStyle for &'_ T {
956 #[inline(always)]
957 fn flex_basis(&self) -> Dimension {
958 (*self).flex_basis()
959 }
960 #[inline(always)]
961 fn flex_grow(&self) -> f32 {
962 (*self).flex_grow()
963 }
964 #[inline(always)]
965 fn flex_shrink(&self) -> f32 {
966 (*self).flex_shrink()
967 }
968 #[inline(always)]
969 fn align_self(&self) -> Option<AlignSelf> {
970 (*self).align_self()
971 }
972}
973
974#[cfg(feature = "grid")]
975impl<S: CheapCloneStr> GridContainerStyle for Style<S> {
976 type Repetition<'a>
977 = &'a GridTemplateRepetition<S>
978 where
979 Self: 'a;
980
981 type TemplateTrackList<'a>
982 = core::iter::Map<
983 core::slice::Iter<'a, GridTemplateComponent<S>>,
984 fn(&'a GridTemplateComponent<S>) -> GenericGridTemplateComponent<S, &'a GridTemplateRepetition<S>>,
985 >
986 where
987 Self: 'a;
988
989 type AutoTrackList<'a>
990 = core::iter::Copied<core::slice::Iter<'a, TrackSizingFunction>>
991 where
992 Self: 'a;
993
994 #[cfg(feature = "grid")]
995 type TemplateLineNames<'a>
996 = core::iter::Map<core::slice::Iter<'a, GridTrackVec<S>>, fn(&GridTrackVec<S>) -> core::slice::Iter<'_, S>>
997 where
998 Self: 'a;
999 #[cfg(feature = "grid")]
1000 type GridTemplateAreas<'a>
1001 = core::iter::Cloned<core::slice::Iter<'a, GridTemplateArea<S>>>
1002 where
1003 Self: 'a;
1004
1005 #[inline(always)]
1006 fn grid_template_rows(&self) -> Option<Self::TemplateTrackList<'_>> {
1007 Some(self.grid_template_rows.iter().map(|c| c.as_component_ref()))
1008 }
1009 #[inline(always)]
1010 fn grid_template_columns(&self) -> Option<Self::TemplateTrackList<'_>> {
1011 Some(self.grid_template_columns.iter().map(|c| c.as_component_ref()))
1012 }
1013 #[inline(always)]
1014 fn grid_auto_rows(&self) -> Self::AutoTrackList<'_> {
1015 self.grid_auto_rows.iter().copied()
1016 }
1017 #[inline(always)]
1018 fn grid_auto_columns(&self) -> Self::AutoTrackList<'_> {
1019 self.grid_auto_columns.iter().copied()
1020 }
1021 #[inline(always)]
1022 fn grid_auto_flow(&self) -> GridAutoFlow {
1023 self.grid_auto_flow
1024 }
1025 #[inline(always)]
1026 fn gap(&self) -> Size<LengthPercentage> {
1027 self.gap
1028 }
1029 #[inline(always)]
1030 fn align_content(&self) -> Option<AlignContent> {
1031 self.align_content
1032 }
1033 #[inline(always)]
1034 fn justify_content(&self) -> Option<JustifyContent> {
1035 self.justify_content
1036 }
1037 #[inline(always)]
1038 fn align_items(&self) -> Option<AlignItems> {
1039 self.align_items
1040 }
1041 #[inline(always)]
1042 fn justify_items(&self) -> Option<AlignItems> {
1043 self.justify_items
1044 }
1045
1046 #[inline(always)]
1047 #[cfg(feature = "grid")]
1048 fn grid_template_areas(&self) -> Option<Self::GridTemplateAreas<'_>> {
1049 Some(self.grid_template_areas.iter().cloned())
1050 }
1051
1052 #[inline(always)]
1053 #[cfg(feature = "grid")]
1054 fn grid_template_column_names(&self) -> Option<Self::TemplateLineNames<'_>> {
1055 Some(self.grid_template_column_names.iter().map(|names| names.iter()))
1056 }
1057
1058 #[inline(always)]
1059 #[cfg(feature = "grid")]
1060 fn grid_template_row_names(&self) -> Option<Self::TemplateLineNames<'_>> {
1061 Some(self.grid_template_row_names.iter().map(|names| names.iter()))
1062 }
1063}
1064
1065#[cfg(feature = "grid")]
1066impl<T: GridContainerStyle> GridContainerStyle for &'_ T {
1067 type Repetition<'a>
1068 = T::Repetition<'a>
1069 where
1070 Self: 'a;
1071
1072 type TemplateTrackList<'a>
1073 = T::TemplateTrackList<'a>
1074 where
1075 Self: 'a;
1076
1077 type AutoTrackList<'a>
1078 = T::AutoTrackList<'a>
1079 where
1080 Self: 'a;
1081
1082 #[cfg(feature = "grid")]
1084 type TemplateLineNames<'a>
1085 = T::TemplateLineNames<'a>
1086 where
1087 Self: 'a;
1088 #[cfg(feature = "grid")]
1089 type GridTemplateAreas<'a>
1090 = T::GridTemplateAreas<'a>
1091 where
1092 Self: 'a;
1093
1094 #[inline(always)]
1095 fn grid_template_rows(&self) -> Option<Self::TemplateTrackList<'_>> {
1096 (*self).grid_template_rows()
1097 }
1098 #[inline(always)]
1099 fn grid_template_columns(&self) -> Option<Self::TemplateTrackList<'_>> {
1100 (*self).grid_template_columns()
1101 }
1102 #[inline(always)]
1103 fn grid_auto_rows(&self) -> Self::AutoTrackList<'_> {
1104 (*self).grid_auto_rows()
1105 }
1106 #[inline(always)]
1107 fn grid_auto_columns(&self) -> Self::AutoTrackList<'_> {
1108 (*self).grid_auto_columns()
1109 }
1110 #[cfg(feature = "grid")]
1111 #[inline(always)]
1112 fn grid_template_areas(&self) -> Option<Self::GridTemplateAreas<'_>> {
1113 (*self).grid_template_areas()
1114 }
1115 #[cfg(feature = "grid")]
1116 #[inline(always)]
1117 fn grid_template_column_names(&self) -> Option<Self::TemplateLineNames<'_>> {
1118 (*self).grid_template_column_names()
1119 }
1120 #[cfg(feature = "grid")]
1121 #[inline(always)]
1122 fn grid_template_row_names(&self) -> Option<Self::TemplateLineNames<'_>> {
1123 (*self).grid_template_row_names()
1124 }
1125 #[inline(always)]
1126 fn grid_auto_flow(&self) -> GridAutoFlow {
1127 (*self).grid_auto_flow()
1128 }
1129 #[inline(always)]
1130 fn gap(&self) -> Size<LengthPercentage> {
1131 (*self).gap()
1132 }
1133 #[inline(always)]
1134 fn align_content(&self) -> Option<AlignContent> {
1135 (*self).align_content()
1136 }
1137 #[inline(always)]
1138 fn justify_content(&self) -> Option<JustifyContent> {
1139 (*self).justify_content()
1140 }
1141 #[inline(always)]
1142 fn align_items(&self) -> Option<AlignItems> {
1143 (*self).align_items()
1144 }
1145 #[inline(always)]
1146 fn justify_items(&self) -> Option<AlignItems> {
1147 (*self).justify_items()
1148 }
1149}
1150
1151#[cfg(feature = "grid")]
1152impl<S: CheapCloneStr> GridItemStyle for Style<S> {
1153 #[inline(always)]
1154 fn grid_row(&self) -> Line<GridPlacement<S>> {
1155 self.grid_row.clone()
1157 }
1158 #[inline(always)]
1159 fn grid_column(&self) -> Line<GridPlacement<S>> {
1160 self.grid_column.clone()
1162 }
1163 #[inline(always)]
1164 fn align_self(&self) -> Option<AlignSelf> {
1165 self.align_self
1166 }
1167 #[inline(always)]
1168 fn justify_self(&self) -> Option<AlignSelf> {
1169 self.justify_self
1170 }
1171}
1172
1173#[cfg(feature = "grid")]
1174impl<T: GridItemStyle> GridItemStyle for &'_ T {
1175 #[inline(always)]
1176 fn grid_row(&self) -> Line<GridPlacement<Self::CustomIdent>> {
1177 (*self).grid_row()
1178 }
1179 #[inline(always)]
1180 fn grid_column(&self) -> Line<GridPlacement<Self::CustomIdent>> {
1181 (*self).grid_column()
1182 }
1183 #[inline(always)]
1184 fn align_self(&self) -> Option<AlignSelf> {
1185 (*self).align_self()
1186 }
1187 #[inline(always)]
1188 fn justify_self(&self) -> Option<AlignSelf> {
1189 (*self).justify_self()
1190 }
1191}
1192
1193#[cfg(test)]
1194mod tests {
1195 use std::sync::Arc;
1196
1197 use super::Style;
1198 use crate::sys::DefaultCheapStr;
1199 use crate::{geometry::*, style_helpers::TaffyAuto as _};
1200
1201 #[test]
1202 fn defaults_match() {
1203 #[cfg(feature = "grid")]
1204 use super::GridPlacement;
1205
1206 let old_defaults: Style<DefaultCheapStr> = Style {
1207 dummy: core::marker::PhantomData,
1208 display: Default::default(),
1209 item_is_table: false,
1210 item_is_replaced: false,
1211 box_sizing: Default::default(),
1212 #[cfg(feature = "float_layout")]
1213 float: Default::default(),
1214 #[cfg(feature = "float_layout")]
1215 clear: Default::default(),
1216 direction: Default::default(),
1217 overflow: Default::default(),
1218 scrollbar_width: 0.0,
1219 position: Default::default(),
1220 #[cfg(feature = "flexbox")]
1221 flex_direction: Default::default(),
1222 #[cfg(feature = "flexbox")]
1223 flex_wrap: Default::default(),
1224 #[cfg(any(feature = "flexbox", feature = "grid"))]
1225 align_items: Default::default(),
1226 #[cfg(any(feature = "flexbox", feature = "grid"))]
1227 align_self: Default::default(),
1228 #[cfg(feature = "grid")]
1229 justify_items: Default::default(),
1230 #[cfg(feature = "grid")]
1231 justify_self: Default::default(),
1232 #[cfg(any(feature = "flexbox", feature = "grid", feature = "block_layout"))]
1233 align_content: Default::default(),
1234 #[cfg(any(feature = "flexbox", feature = "grid"))]
1235 justify_content: Default::default(),
1236 inset: Rect::auto(),
1237 margin: Rect::zero(),
1238 padding: Rect::zero(),
1239 border: Rect::zero(),
1240 gap: Size::zero(),
1241 #[cfg(feature = "block_layout")]
1242 text_align: Default::default(),
1243 #[cfg(feature = "flexbox")]
1244 flex_grow: 0.0,
1245 #[cfg(feature = "flexbox")]
1246 flex_shrink: 1.0,
1247 #[cfg(feature = "flexbox")]
1248 flex_basis: super::Dimension::AUTO,
1249 size: Size::auto(),
1250 min_size: Size::auto(),
1251 max_size: Size::auto(),
1252 aspect_ratio: Default::default(),
1253 #[cfg(feature = "grid")]
1254 grid_template_rows: Default::default(),
1255 #[cfg(feature = "grid")]
1256 grid_template_columns: Default::default(),
1257 #[cfg(feature = "grid")]
1258 grid_template_row_names: Default::default(),
1259 #[cfg(feature = "grid")]
1260 grid_template_column_names: Default::default(),
1261 #[cfg(feature = "grid")]
1262 grid_template_areas: Default::default(),
1263 #[cfg(feature = "grid")]
1264 grid_auto_rows: Default::default(),
1265 #[cfg(feature = "grid")]
1266 grid_auto_columns: Default::default(),
1267 #[cfg(feature = "grid")]
1268 grid_auto_flow: Default::default(),
1269 #[cfg(feature = "grid")]
1270 grid_row: Line { start: GridPlacement::Auto, end: GridPlacement::Auto },
1271 #[cfg(feature = "grid")]
1272 grid_column: Line { start: GridPlacement::Auto, end: GridPlacement::Auto },
1273 };
1274
1275 assert_eq!(Style::DEFAULT, Style::<DefaultCheapStr>::default());
1276 assert_eq!(Style::DEFAULT, old_defaults);
1277 }
1278
1279 #[test]
1282 fn style_sizes() {
1283 use super::*;
1284 type S = crate::sys::DefaultCheapStr;
1285
1286 fn assert_type_size<T>(expected_size: usize) {
1287 let name = ::core::any::type_name::<T>();
1288 let name = name.replace("taffy::geometry::", "");
1289 let name = name.replace("taffy::style::dimension::", "");
1290 let name = name.replace("taffy::style::alignment::", "");
1291 let name = name.replace("taffy::style::flex::", "");
1292 let name = name.replace("taffy::style::grid::", "");
1293
1294 assert_eq!(
1295 ::core::mem::size_of::<T>(),
1296 expected_size,
1297 "Expected {} for be {} byte(s) but it was {} byte(s)",
1298 name,
1299 expected_size,
1300 ::core::mem::size_of::<T>(),
1301 );
1302 }
1303
1304 assert_type_size::<Display>(1);
1306 assert_type_size::<BoxSizing>(1);
1307 assert_type_size::<Position>(1);
1308 assert_type_size::<Overflow>(1);
1309
1310 assert_type_size::<f32>(4);
1312 assert_type_size::<LengthPercentage>(8);
1313 assert_type_size::<LengthPercentageAuto>(8);
1314 assert_type_size::<Dimension>(8);
1315 assert_type_size::<Size<LengthPercentage>>(16);
1316 assert_type_size::<Size<LengthPercentageAuto>>(16);
1317 assert_type_size::<Size<Dimension>>(16);
1318 assert_type_size::<Rect<LengthPercentage>>(32);
1319 assert_type_size::<Rect<LengthPercentageAuto>>(32);
1320 assert_type_size::<Rect<Dimension>>(32);
1321
1322 assert_type_size::<AlignContentKeyword>(1);
1326 assert_type_size::<AlignItemsKeyword>(1);
1327 assert_type_size::<AlignmentSafety>(1);
1328 assert_type_size::<AlignContent>(2);
1329 assert_type_size::<AlignItems>(2);
1330 assert_type_size::<Option<AlignItems>>(2);
1331 assert_type_size::<Option<AlignContent>>(2);
1332
1333 assert_type_size::<FlexDirection>(1);
1335 assert_type_size::<FlexWrap>(1);
1336
1337 assert_type_size::<GridAutoFlow>(1);
1339 assert_type_size::<MinTrackSizingFunction>(8);
1340 assert_type_size::<MaxTrackSizingFunction>(8);
1341 assert_type_size::<TrackSizingFunction>(16);
1342 assert_type_size::<Vec<TrackSizingFunction>>(24);
1343 assert_type_size::<Vec<GridTemplateComponent<S>>>(24);
1344
1345 assert_type_size::<GridTemplateComponent<String>>(56);
1347 assert_type_size::<GridPlacement<String>>(32);
1348 assert_type_size::<Line<GridPlacement<String>>>(64);
1349 assert_type_size::<Style<String>>(544);
1350
1351 assert_type_size::<GridTemplateComponent<Arc<str>>>(56);
1353 assert_type_size::<GridPlacement<Arc<str>>>(24);
1354 assert_type_size::<Line<GridPlacement<Arc<str>>>>(48);
1355 assert_type_size::<Style<Arc<str>>>(512);
1356 }
1357}