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"))]
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"))]
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
820#[cfg(feature = "block_layout")]
821impl<T: BlockContainerStyle> BlockContainerStyle for &'_ T {
822 #[inline(always)]
823 fn text_align(&self) -> TextAlign {
824 (*self).text_align()
825 }
826}
827
828#[cfg(feature = "block_layout")]
829impl<S: CheapCloneStr> BlockItemStyle for Style<S> {
830 #[inline(always)]
831 fn is_table(&self) -> bool {
832 self.item_is_table
833 }
834
835 #[cfg(feature = "float_layout")]
836 #[inline(always)]
837 fn float(&self) -> Float {
838 self.float
839 }
840
841 #[cfg(feature = "float_layout")]
842 #[inline(always)]
843 fn clear(&self) -> Clear {
844 self.clear
845 }
846}
847
848#[cfg(feature = "block_layout")]
849impl<T: BlockItemStyle> BlockItemStyle for &'_ T {
850 #[inline(always)]
851 fn is_table(&self) -> bool {
852 (*self).is_table()
853 }
854
855 #[cfg(feature = "float_layout")]
856 #[inline(always)]
857 fn float(&self) -> Float {
858 (*self).float()
859 }
860
861 #[cfg(feature = "float_layout")]
862 #[inline(always)]
863 fn clear(&self) -> Clear {
864 (*self).clear()
865 }
866}
867
868#[cfg(feature = "flexbox")]
869impl<S: CheapCloneStr> FlexboxContainerStyle for Style<S> {
870 #[inline(always)]
871 fn flex_direction(&self) -> FlexDirection {
872 self.flex_direction
873 }
874 #[inline(always)]
875 fn flex_wrap(&self) -> FlexWrap {
876 self.flex_wrap
877 }
878 #[inline(always)]
879 fn gap(&self) -> Size<LengthPercentage> {
880 self.gap
881 }
882 #[inline(always)]
883 fn align_content(&self) -> Option<AlignContent> {
884 self.align_content
885 }
886 #[inline(always)]
887 fn align_items(&self) -> Option<AlignItems> {
888 self.align_items
889 }
890 #[inline(always)]
891 fn justify_content(&self) -> Option<JustifyContent> {
892 self.justify_content
893 }
894}
895
896#[cfg(feature = "flexbox")]
897impl<T: FlexboxContainerStyle> FlexboxContainerStyle for &'_ T {
898 #[inline(always)]
899 fn flex_direction(&self) -> FlexDirection {
900 (*self).flex_direction()
901 }
902 #[inline(always)]
903 fn flex_wrap(&self) -> FlexWrap {
904 (*self).flex_wrap()
905 }
906 #[inline(always)]
907 fn gap(&self) -> Size<LengthPercentage> {
908 (*self).gap()
909 }
910 #[inline(always)]
911 fn align_content(&self) -> Option<AlignContent> {
912 (*self).align_content()
913 }
914 #[inline(always)]
915 fn align_items(&self) -> Option<AlignItems> {
916 (*self).align_items()
917 }
918 #[inline(always)]
919 fn justify_content(&self) -> Option<JustifyContent> {
920 (*self).justify_content()
921 }
922}
923
924#[cfg(feature = "flexbox")]
925impl<S: CheapCloneStr> FlexboxItemStyle for Style<S> {
926 #[inline(always)]
927 fn flex_basis(&self) -> Dimension {
928 self.flex_basis
929 }
930 #[inline(always)]
931 fn flex_grow(&self) -> f32 {
932 self.flex_grow
933 }
934 #[inline(always)]
935 fn flex_shrink(&self) -> f32 {
936 self.flex_shrink
937 }
938 #[inline(always)]
939 fn align_self(&self) -> Option<AlignSelf> {
940 self.align_self
941 }
942}
943
944#[cfg(feature = "flexbox")]
945impl<T: FlexboxItemStyle> FlexboxItemStyle for &'_ T {
946 #[inline(always)]
947 fn flex_basis(&self) -> Dimension {
948 (*self).flex_basis()
949 }
950 #[inline(always)]
951 fn flex_grow(&self) -> f32 {
952 (*self).flex_grow()
953 }
954 #[inline(always)]
955 fn flex_shrink(&self) -> f32 {
956 (*self).flex_shrink()
957 }
958 #[inline(always)]
959 fn align_self(&self) -> Option<AlignSelf> {
960 (*self).align_self()
961 }
962}
963
964#[cfg(feature = "grid")]
965impl<S: CheapCloneStr> GridContainerStyle for Style<S> {
966 type Repetition<'a>
967 = &'a GridTemplateRepetition<S>
968 where
969 Self: 'a;
970
971 type TemplateTrackList<'a>
972 = core::iter::Map<
973 core::slice::Iter<'a, GridTemplateComponent<S>>,
974 fn(&'a GridTemplateComponent<S>) -> GenericGridTemplateComponent<S, &'a GridTemplateRepetition<S>>,
975 >
976 where
977 Self: 'a;
978
979 type AutoTrackList<'a>
980 = core::iter::Copied<core::slice::Iter<'a, TrackSizingFunction>>
981 where
982 Self: 'a;
983
984 #[cfg(feature = "grid")]
985 type TemplateLineNames<'a>
986 = core::iter::Map<core::slice::Iter<'a, GridTrackVec<S>>, fn(&GridTrackVec<S>) -> core::slice::Iter<'_, S>>
987 where
988 Self: 'a;
989 #[cfg(feature = "grid")]
990 type GridTemplateAreas<'a>
991 = core::iter::Cloned<core::slice::Iter<'a, GridTemplateArea<S>>>
992 where
993 Self: 'a;
994
995 #[inline(always)]
996 fn grid_template_rows(&self) -> Option<Self::TemplateTrackList<'_>> {
997 Some(self.grid_template_rows.iter().map(|c| c.as_component_ref()))
998 }
999 #[inline(always)]
1000 fn grid_template_columns(&self) -> Option<Self::TemplateTrackList<'_>> {
1001 Some(self.grid_template_columns.iter().map(|c| c.as_component_ref()))
1002 }
1003 #[inline(always)]
1004 fn grid_auto_rows(&self) -> Self::AutoTrackList<'_> {
1005 self.grid_auto_rows.iter().copied()
1006 }
1007 #[inline(always)]
1008 fn grid_auto_columns(&self) -> Self::AutoTrackList<'_> {
1009 self.grid_auto_columns.iter().copied()
1010 }
1011 #[inline(always)]
1012 fn grid_auto_flow(&self) -> GridAutoFlow {
1013 self.grid_auto_flow
1014 }
1015 #[inline(always)]
1016 fn gap(&self) -> Size<LengthPercentage> {
1017 self.gap
1018 }
1019 #[inline(always)]
1020 fn align_content(&self) -> Option<AlignContent> {
1021 self.align_content
1022 }
1023 #[inline(always)]
1024 fn justify_content(&self) -> Option<JustifyContent> {
1025 self.justify_content
1026 }
1027 #[inline(always)]
1028 fn align_items(&self) -> Option<AlignItems> {
1029 self.align_items
1030 }
1031 #[inline(always)]
1032 fn justify_items(&self) -> Option<AlignItems> {
1033 self.justify_items
1034 }
1035
1036 #[inline(always)]
1037 #[cfg(feature = "grid")]
1038 fn grid_template_areas(&self) -> Option<Self::GridTemplateAreas<'_>> {
1039 Some(self.grid_template_areas.iter().cloned())
1040 }
1041
1042 #[inline(always)]
1043 #[cfg(feature = "grid")]
1044 fn grid_template_column_names(&self) -> Option<Self::TemplateLineNames<'_>> {
1045 Some(self.grid_template_column_names.iter().map(|names| names.iter()))
1046 }
1047
1048 #[inline(always)]
1049 #[cfg(feature = "grid")]
1050 fn grid_template_row_names(&self) -> Option<Self::TemplateLineNames<'_>> {
1051 Some(self.grid_template_row_names.iter().map(|names| names.iter()))
1052 }
1053}
1054
1055#[cfg(feature = "grid")]
1056impl<T: GridContainerStyle> GridContainerStyle for &'_ T {
1057 type Repetition<'a>
1058 = T::Repetition<'a>
1059 where
1060 Self: 'a;
1061
1062 type TemplateTrackList<'a>
1063 = T::TemplateTrackList<'a>
1064 where
1065 Self: 'a;
1066
1067 type AutoTrackList<'a>
1068 = T::AutoTrackList<'a>
1069 where
1070 Self: 'a;
1071
1072 #[cfg(feature = "grid")]
1074 type TemplateLineNames<'a>
1075 = T::TemplateLineNames<'a>
1076 where
1077 Self: 'a;
1078 #[cfg(feature = "grid")]
1079 type GridTemplateAreas<'a>
1080 = T::GridTemplateAreas<'a>
1081 where
1082 Self: 'a;
1083
1084 #[inline(always)]
1085 fn grid_template_rows(&self) -> Option<Self::TemplateTrackList<'_>> {
1086 (*self).grid_template_rows()
1087 }
1088 #[inline(always)]
1089 fn grid_template_columns(&self) -> Option<Self::TemplateTrackList<'_>> {
1090 (*self).grid_template_columns()
1091 }
1092 #[inline(always)]
1093 fn grid_auto_rows(&self) -> Self::AutoTrackList<'_> {
1094 (*self).grid_auto_rows()
1095 }
1096 #[inline(always)]
1097 fn grid_auto_columns(&self) -> Self::AutoTrackList<'_> {
1098 (*self).grid_auto_columns()
1099 }
1100 #[cfg(feature = "grid")]
1101 #[inline(always)]
1102 fn grid_template_areas(&self) -> Option<Self::GridTemplateAreas<'_>> {
1103 (*self).grid_template_areas()
1104 }
1105 #[cfg(feature = "grid")]
1106 #[inline(always)]
1107 fn grid_template_column_names(&self) -> Option<Self::TemplateLineNames<'_>> {
1108 (*self).grid_template_column_names()
1109 }
1110 #[cfg(feature = "grid")]
1111 #[inline(always)]
1112 fn grid_template_row_names(&self) -> Option<Self::TemplateLineNames<'_>> {
1113 (*self).grid_template_row_names()
1114 }
1115 #[inline(always)]
1116 fn grid_auto_flow(&self) -> GridAutoFlow {
1117 (*self).grid_auto_flow()
1118 }
1119 #[inline(always)]
1120 fn gap(&self) -> Size<LengthPercentage> {
1121 (*self).gap()
1122 }
1123 #[inline(always)]
1124 fn align_content(&self) -> Option<AlignContent> {
1125 (*self).align_content()
1126 }
1127 #[inline(always)]
1128 fn justify_content(&self) -> Option<JustifyContent> {
1129 (*self).justify_content()
1130 }
1131 #[inline(always)]
1132 fn align_items(&self) -> Option<AlignItems> {
1133 (*self).align_items()
1134 }
1135 #[inline(always)]
1136 fn justify_items(&self) -> Option<AlignItems> {
1137 (*self).justify_items()
1138 }
1139}
1140
1141#[cfg(feature = "grid")]
1142impl<S: CheapCloneStr> GridItemStyle for Style<S> {
1143 #[inline(always)]
1144 fn grid_row(&self) -> Line<GridPlacement<S>> {
1145 self.grid_row.clone()
1147 }
1148 #[inline(always)]
1149 fn grid_column(&self) -> Line<GridPlacement<S>> {
1150 self.grid_column.clone()
1152 }
1153 #[inline(always)]
1154 fn align_self(&self) -> Option<AlignSelf> {
1155 self.align_self
1156 }
1157 #[inline(always)]
1158 fn justify_self(&self) -> Option<AlignSelf> {
1159 self.justify_self
1160 }
1161}
1162
1163#[cfg(feature = "grid")]
1164impl<T: GridItemStyle> GridItemStyle for &'_ T {
1165 #[inline(always)]
1166 fn grid_row(&self) -> Line<GridPlacement<Self::CustomIdent>> {
1167 (*self).grid_row()
1168 }
1169 #[inline(always)]
1170 fn grid_column(&self) -> Line<GridPlacement<Self::CustomIdent>> {
1171 (*self).grid_column()
1172 }
1173 #[inline(always)]
1174 fn align_self(&self) -> Option<AlignSelf> {
1175 (*self).align_self()
1176 }
1177 #[inline(always)]
1178 fn justify_self(&self) -> Option<AlignSelf> {
1179 (*self).justify_self()
1180 }
1181}
1182
1183#[cfg(test)]
1184mod tests {
1185 use std::sync::Arc;
1186
1187 use super::Style;
1188 use crate::sys::DefaultCheapStr;
1189 use crate::{geometry::*, style_helpers::TaffyAuto as _};
1190
1191 #[test]
1192 fn defaults_match() {
1193 #[cfg(feature = "grid")]
1194 use super::GridPlacement;
1195
1196 let old_defaults: Style<DefaultCheapStr> = Style {
1197 dummy: core::marker::PhantomData,
1198 display: Default::default(),
1199 item_is_table: false,
1200 item_is_replaced: false,
1201 box_sizing: Default::default(),
1202 #[cfg(feature = "float_layout")]
1203 float: Default::default(),
1204 #[cfg(feature = "float_layout")]
1205 clear: Default::default(),
1206 direction: Default::default(),
1207 overflow: Default::default(),
1208 scrollbar_width: 0.0,
1209 position: Default::default(),
1210 #[cfg(feature = "flexbox")]
1211 flex_direction: Default::default(),
1212 #[cfg(feature = "flexbox")]
1213 flex_wrap: Default::default(),
1214 #[cfg(any(feature = "flexbox", feature = "grid"))]
1215 align_items: Default::default(),
1216 #[cfg(any(feature = "flexbox", feature = "grid"))]
1217 align_self: Default::default(),
1218 #[cfg(feature = "grid")]
1219 justify_items: Default::default(),
1220 #[cfg(feature = "grid")]
1221 justify_self: Default::default(),
1222 #[cfg(any(feature = "flexbox", feature = "grid"))]
1223 align_content: Default::default(),
1224 #[cfg(any(feature = "flexbox", feature = "grid"))]
1225 justify_content: Default::default(),
1226 inset: Rect::auto(),
1227 margin: Rect::zero(),
1228 padding: Rect::zero(),
1229 border: Rect::zero(),
1230 gap: Size::zero(),
1231 #[cfg(feature = "block_layout")]
1232 text_align: Default::default(),
1233 #[cfg(feature = "flexbox")]
1234 flex_grow: 0.0,
1235 #[cfg(feature = "flexbox")]
1236 flex_shrink: 1.0,
1237 #[cfg(feature = "flexbox")]
1238 flex_basis: super::Dimension::AUTO,
1239 size: Size::auto(),
1240 min_size: Size::auto(),
1241 max_size: Size::auto(),
1242 aspect_ratio: Default::default(),
1243 #[cfg(feature = "grid")]
1244 grid_template_rows: Default::default(),
1245 #[cfg(feature = "grid")]
1246 grid_template_columns: Default::default(),
1247 #[cfg(feature = "grid")]
1248 grid_template_row_names: Default::default(),
1249 #[cfg(feature = "grid")]
1250 grid_template_column_names: Default::default(),
1251 #[cfg(feature = "grid")]
1252 grid_template_areas: Default::default(),
1253 #[cfg(feature = "grid")]
1254 grid_auto_rows: Default::default(),
1255 #[cfg(feature = "grid")]
1256 grid_auto_columns: Default::default(),
1257 #[cfg(feature = "grid")]
1258 grid_auto_flow: Default::default(),
1259 #[cfg(feature = "grid")]
1260 grid_row: Line { start: GridPlacement::Auto, end: GridPlacement::Auto },
1261 #[cfg(feature = "grid")]
1262 grid_column: Line { start: GridPlacement::Auto, end: GridPlacement::Auto },
1263 };
1264
1265 assert_eq!(Style::DEFAULT, Style::<DefaultCheapStr>::default());
1266 assert_eq!(Style::DEFAULT, old_defaults);
1267 }
1268
1269 #[test]
1272 fn style_sizes() {
1273 use super::*;
1274 type S = crate::sys::DefaultCheapStr;
1275
1276 fn assert_type_size<T>(expected_size: usize) {
1277 let name = ::core::any::type_name::<T>();
1278 let name = name.replace("taffy::geometry::", "");
1279 let name = name.replace("taffy::style::dimension::", "");
1280 let name = name.replace("taffy::style::alignment::", "");
1281 let name = name.replace("taffy::style::flex::", "");
1282 let name = name.replace("taffy::style::grid::", "");
1283
1284 assert_eq!(
1285 ::core::mem::size_of::<T>(),
1286 expected_size,
1287 "Expected {} for be {} byte(s) but it was {} byte(s)",
1288 name,
1289 expected_size,
1290 ::core::mem::size_of::<T>(),
1291 );
1292 }
1293
1294 assert_type_size::<Display>(1);
1296 assert_type_size::<BoxSizing>(1);
1297 assert_type_size::<Position>(1);
1298 assert_type_size::<Overflow>(1);
1299
1300 assert_type_size::<f32>(4);
1302 assert_type_size::<LengthPercentage>(8);
1303 assert_type_size::<LengthPercentageAuto>(8);
1304 assert_type_size::<Dimension>(8);
1305 assert_type_size::<Size<LengthPercentage>>(16);
1306 assert_type_size::<Size<LengthPercentageAuto>>(16);
1307 assert_type_size::<Size<Dimension>>(16);
1308 assert_type_size::<Rect<LengthPercentage>>(32);
1309 assert_type_size::<Rect<LengthPercentageAuto>>(32);
1310 assert_type_size::<Rect<Dimension>>(32);
1311
1312 assert_type_size::<AlignContentKeyword>(1);
1316 assert_type_size::<AlignItemsKeyword>(1);
1317 assert_type_size::<AlignmentSafety>(1);
1318 assert_type_size::<AlignContent>(2);
1319 assert_type_size::<AlignItems>(2);
1320 assert_type_size::<Option<AlignItems>>(2);
1321 assert_type_size::<Option<AlignContent>>(2);
1322
1323 assert_type_size::<FlexDirection>(1);
1325 assert_type_size::<FlexWrap>(1);
1326
1327 assert_type_size::<GridAutoFlow>(1);
1329 assert_type_size::<MinTrackSizingFunction>(8);
1330 assert_type_size::<MaxTrackSizingFunction>(8);
1331 assert_type_size::<TrackSizingFunction>(16);
1332 assert_type_size::<Vec<TrackSizingFunction>>(24);
1333 assert_type_size::<Vec<GridTemplateComponent<S>>>(24);
1334
1335 assert_type_size::<GridTemplateComponent<String>>(56);
1337 assert_type_size::<GridPlacement<String>>(32);
1338 assert_type_size::<Line<GridPlacement<String>>>(64);
1339 assert_type_size::<Style<String>>(544);
1340
1341 assert_type_size::<GridTemplateComponent<Arc<str>>>(56);
1343 assert_type_size::<GridPlacement<Arc<str>>>(24);
1344 assert_type_size::<Line<GridPlacement<Arc<str>>>>(48);
1345 assert_type_size::<Style<Arc<str>>>(512);
1346 }
1347}