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, GridTemplateAreas, 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)]
97 fn is_block(&self) -> bool {
98 false
99 }
100 #[inline(always)]
103 fn is_compressible_replaced(&self) -> bool {
104 false
105 }
106 #[inline(always)]
108 fn box_sizing(&self) -> BoxSizing {
109 BoxSizing::BorderBox
110 }
111
112 #[inline(always)]
114 fn direction(&self) -> Direction {
115 Direction::Ltr
116 }
117
118 #[inline(always)]
121 fn overflow(&self) -> Point<Overflow> {
122 Style::<Self::CustomIdent>::DEFAULT.overflow
123 }
124 #[inline(always)]
126 fn scrollbar_width(&self) -> f32 {
127 0.0
128 }
129
130 #[inline(always)]
133 fn position(&self) -> Position {
134 Style::<Self::CustomIdent>::DEFAULT.position
135 }
136 #[inline(always)]
138 fn inset(&self) -> Rect<LengthPercentageAuto> {
139 Style::<Self::CustomIdent>::DEFAULT.inset
140 }
141
142 #[inline(always)]
145 fn size(&self) -> Size<Dimension> {
146 Style::<Self::CustomIdent>::DEFAULT.size
147 }
148 #[inline(always)]
150 fn min_size(&self) -> Size<Dimension> {
151 Style::<Self::CustomIdent>::DEFAULT.min_size
152 }
153 #[inline(always)]
155 fn max_size(&self) -> Size<Dimension> {
156 Style::<Self::CustomIdent>::DEFAULT.max_size
157 }
158 #[inline(always)]
161 fn aspect_ratio(&self) -> Option<f32> {
162 Style::<Self::CustomIdent>::DEFAULT.aspect_ratio
163 }
164
165 #[inline(always)]
168 fn margin(&self) -> Rect<LengthPercentageAuto> {
169 Style::<Self::CustomIdent>::DEFAULT.margin
170 }
171 #[inline(always)]
173 fn padding(&self) -> Rect<LengthPercentage> {
174 Style::<Self::CustomIdent>::DEFAULT.padding
175 }
176 #[inline(always)]
178 fn border(&self) -> Rect<LengthPercentage> {
179 Style::<Self::CustomIdent>::DEFAULT.border
180 }
181}
182
183#[derive(Copy, Clone, PartialEq, Eq, Debug)]
187#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
188pub enum Display {
189 #[cfg(feature = "block_layout")]
191 Block,
192 #[cfg(feature = "block_layout")]
194 FlowRoot,
195 #[cfg(feature = "flexbox")]
197 Flex,
198 #[cfg(feature = "grid")]
200 Grid,
201 None,
203}
204
205impl Display {
206 #[cfg(feature = "flexbox")]
208 pub const DEFAULT: Display = Display::Flex;
209
210 #[cfg(all(feature = "grid", not(feature = "flexbox")))]
212 pub const DEFAULT: Display = Display::Grid;
213
214 #[cfg(all(feature = "block_layout", not(feature = "flexbox"), not(feature = "grid")))]
216 pub const DEFAULT: Display = Display::Block;
217
218 #[cfg(all(not(feature = "flexbox"), not(feature = "grid"), not(feature = "block_layout")))]
220 pub const DEFAULT: Display = Display::None;
221}
222
223impl Default for Display {
224 fn default() -> Self {
225 Self::DEFAULT
226 }
227}
228
229#[cfg(feature = "parse")]
230crate::util::parse::impl_parse_for_keyword_enum!(Display,
231 "none" => None,
232 #[cfg(feature = "flexbox")]
233 "flex" => Flex,
234 #[cfg(feature = "grid")]
235 "grid" => Grid,
236 #[cfg(feature = "block_layout")]
237 "block" => Block,
238 #[cfg(feature = "block_layout")]
239 "flow-root" => FlowRoot,
240);
241
242impl core::fmt::Display for Display {
243 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
244 match self {
245 Display::None => write!(f, "NONE"),
246 #[cfg(feature = "block_layout")]
247 Display::Block => write!(f, "BLOCK"),
248 #[cfg(feature = "block_layout")]
249 Display::FlowRoot => write!(f, "FLOW-ROOT"),
250 #[cfg(feature = "flexbox")]
251 Display::Flex => write!(f, "FLEX"),
252 #[cfg(feature = "grid")]
253 Display::Grid => write!(f, "GRID"),
254 }
255 }
256}
257
258#[derive(Copy, Clone, PartialEq, Eq, Debug)]
261#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
262pub enum BoxGenerationMode {
263 Normal,
265 None,
267}
268
269impl BoxGenerationMode {
270 pub const DEFAULT: BoxGenerationMode = BoxGenerationMode::Normal;
272}
273
274impl Default for BoxGenerationMode {
275 fn default() -> Self {
276 Self::DEFAULT
277 }
278}
279
280#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)]
290#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
291pub enum Position {
292 #[default]
295 Relative,
296 Absolute,
302}
303
304#[cfg(feature = "parse")]
305crate::util::parse::impl_parse_for_keyword_enum!(Position,
306 "relative" => Relative,
307 "absolute" => Absolute,
308);
309
310#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)]
324#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
325pub enum BoxSizing {
326 #[default]
328 BorderBox,
329 ContentBox,
331}
332
333#[cfg(feature = "parse")]
334crate::util::parse::impl_parse_for_keyword_enum!(BoxSizing,
335 "border-box" => BorderBox,
336 "content-box" => ContentBox,
337);
338
339#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)]
353#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
354pub enum Overflow {
355 #[default]
358 Visible,
359 Clip,
362 Hidden,
365 Scroll,
369}
370
371impl Overflow {
372 #[inline(always)]
375 pub fn is_scroll_container(self) -> bool {
376 match self {
377 Self::Visible | Self::Clip => false,
378 Self::Hidden | Self::Scroll => true,
379 }
380 }
381
382 #[inline(always)]
385 pub(crate) fn maybe_into_automatic_min_size(self) -> Option<f32> {
386 match self.is_scroll_container() {
387 true => Some(0.0),
388 false => None,
389 }
390 }
391}
392
393#[cfg(feature = "parse")]
394crate::util::parse::impl_parse_for_keyword_enum!(Overflow,
395 "visible" => Visible,
396 "hidden" => Hidden,
397 "clip" => Clip,
398 "scroll" => Scroll,
399);
400
401#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)]
404#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
405pub enum Direction {
406 #[default]
407 Ltr,
409 Rtl,
411}
412
413impl Direction {
414 #[inline]
416 pub(crate) fn is_rtl(&self) -> bool {
417 matches!(self, Direction::Rtl)
418 }
419}
420
421#[cfg(feature = "parse")]
422crate::util::parse::impl_parse_for_keyword_enum!(Direction,
423 "ltr" => Ltr,
424 "rtl" => Rtl,
425);
426
427#[derive(Clone, PartialEq, Debug)]
442#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
443#[cfg_attr(feature = "serde", serde(default))]
444pub struct Style<S: CheapCloneStr = DefaultCheapStr> {
445 pub dummy: core::marker::PhantomData<S>,
448 pub display: Display,
450 pub item_is_table: bool,
453 pub item_is_replaced: bool,
456 pub box_sizing: BoxSizing,
458 pub direction: Direction,
460
461 pub overflow: Point<Overflow>,
464 pub scrollbar_width: f32,
466
467 #[cfg(feature = "float_layout")]
468 pub float: Float,
470 #[cfg(feature = "float_layout")]
471 pub clear: Clear,
473
474 pub position: Position,
477 #[cfg_attr(feature = "serde", serde(default = "style_helpers::auto"))]
479 pub inset: Rect<LengthPercentageAuto>,
480
481 #[cfg_attr(feature = "serde", serde(default = "style_helpers::auto"))]
484 pub size: Size<Dimension>,
485 #[cfg_attr(feature = "serde", serde(default = "style_helpers::auto"))]
487 pub min_size: Size<Dimension>,
488 #[cfg_attr(feature = "serde", serde(default = "style_helpers::auto"))]
490 pub max_size: Size<Dimension>,
491 pub aspect_ratio: Option<f32>,
495
496 #[cfg_attr(feature = "serde", serde(default = "style_helpers::zero"))]
499 pub margin: Rect<LengthPercentageAuto>,
500 #[cfg_attr(feature = "serde", serde(default = "style_helpers::zero"))]
502 pub padding: Rect<LengthPercentage>,
503 #[cfg_attr(feature = "serde", serde(default = "style_helpers::zero"))]
505 pub border: Rect<LengthPercentage>,
506
507 #[cfg(any(feature = "flexbox", feature = "grid"))]
510 pub align_items: Option<AlignItems>,
511 #[cfg(any(feature = "flexbox", feature = "grid"))]
514 pub align_self: Option<AlignSelf>,
515 #[cfg(feature = "grid")]
517 pub justify_items: Option<AlignItems>,
518 #[cfg(feature = "grid")]
521 pub justify_self: Option<AlignSelf>,
522 #[cfg(any(feature = "flexbox", feature = "grid", feature = "block_layout"))]
524 pub align_content: Option<AlignContent>,
525 #[cfg(any(feature = "flexbox", feature = "grid"))]
527 pub justify_content: Option<JustifyContent>,
528 #[cfg(any(feature = "flexbox", feature = "grid"))]
530 #[cfg_attr(feature = "serde", serde(default = "style_helpers::zero"))]
531 pub gap: Size<LengthPercentage>,
532
533 #[cfg(feature = "block_layout")]
536 pub text_align: TextAlign,
537
538 #[cfg(feature = "flexbox")]
541 pub flex_direction: FlexDirection,
542 #[cfg(feature = "flexbox")]
544 pub flex_wrap: FlexWrap,
545
546 #[cfg(feature = "flexbox")]
549 pub flex_basis: Dimension,
550 #[cfg(feature = "flexbox")]
554 pub flex_grow: f32,
555 #[cfg(feature = "flexbox")]
559 pub flex_shrink: f32,
560
561 #[cfg(feature = "grid")]
564 pub grid_template_rows: GridTrackVec<GridTemplateComponent<S>>,
565 #[cfg(feature = "grid")]
567 pub grid_template_columns: GridTrackVec<GridTemplateComponent<S>>,
568 #[cfg(feature = "grid")]
570 pub grid_auto_rows: GridTrackVec<TrackSizingFunction>,
571 #[cfg(feature = "grid")]
573 pub grid_auto_columns: GridTrackVec<TrackSizingFunction>,
574 #[cfg(feature = "grid")]
576 pub grid_auto_flow: GridAutoFlow,
577
578 #[cfg(feature = "grid")]
581 pub grid_template_areas: Option<GridTemplateAreas<S>>,
582 #[cfg(feature = "grid")]
584 pub grid_template_column_names: GridTrackVec<GridTrackVec<S>>,
585 #[cfg(feature = "grid")]
587 pub grid_template_row_names: GridTrackVec<GridTrackVec<S>>,
588
589 #[cfg(feature = "grid")]
592 pub grid_row: Line<GridPlacement<S>>,
593 #[cfg(feature = "grid")]
595 pub grid_column: Line<GridPlacement<S>>,
596}
597
598impl<S: CheapCloneStr> Style<S> {
599 pub const DEFAULT: Style<S> = Style {
601 dummy: core::marker::PhantomData,
602 display: Display::DEFAULT,
603 item_is_table: false,
604 item_is_replaced: false,
605 box_sizing: BoxSizing::BorderBox,
606 direction: Direction::Ltr,
607 overflow: Point { x: Overflow::Visible, y: Overflow::Visible },
608 scrollbar_width: 0.0,
609 #[cfg(feature = "float_layout")]
610 float: Float::None,
611 #[cfg(feature = "float_layout")]
612 clear: Clear::None,
613 position: Position::Relative,
614 inset: Rect::auto(),
615 margin: Rect::zero(),
616 padding: Rect::zero(),
617 border: Rect::zero(),
618 size: Size::auto(),
619 min_size: Size::auto(),
620 max_size: Size::auto(),
621 aspect_ratio: None,
622 #[cfg(any(feature = "flexbox", feature = "grid"))]
623 gap: Size::zero(),
624 #[cfg(any(feature = "flexbox", feature = "grid"))]
626 align_items: None,
627 #[cfg(any(feature = "flexbox", feature = "grid"))]
628 align_self: None,
629 #[cfg(feature = "grid")]
630 justify_items: None,
631 #[cfg(feature = "grid")]
632 justify_self: None,
633 #[cfg(any(feature = "flexbox", feature = "grid", feature = "block_layout"))]
634 align_content: None,
635 #[cfg(any(feature = "flexbox", feature = "grid"))]
636 justify_content: None,
637 #[cfg(feature = "block_layout")]
639 text_align: TextAlign::Auto,
640 #[cfg(feature = "flexbox")]
642 flex_direction: FlexDirection::Row,
643 #[cfg(feature = "flexbox")]
644 flex_wrap: FlexWrap::NoWrap,
645 #[cfg(feature = "flexbox")]
646 flex_grow: 0.0,
647 #[cfg(feature = "flexbox")]
648 flex_shrink: 1.0,
649 #[cfg(feature = "flexbox")]
650 flex_basis: Dimension::AUTO,
651 #[cfg(feature = "grid")]
653 grid_template_rows: GridTrackVec::new(),
654 #[cfg(feature = "grid")]
655 grid_template_columns: GridTrackVec::new(),
656 #[cfg(feature = "grid")]
657 grid_template_areas: None,
658 #[cfg(feature = "grid")]
659 grid_template_column_names: GridTrackVec::new(),
660 #[cfg(feature = "grid")]
661 grid_template_row_names: GridTrackVec::new(),
662 #[cfg(feature = "grid")]
663 grid_auto_rows: GridTrackVec::new(),
664 #[cfg(feature = "grid")]
665 grid_auto_columns: GridTrackVec::new(),
666 #[cfg(feature = "grid")]
667 grid_auto_flow: GridAutoFlow::Row,
668 #[cfg(feature = "grid")]
669 grid_row: Line { start: GridPlacement::<S>::Auto, end: GridPlacement::<S>::Auto },
670 #[cfg(feature = "grid")]
671 grid_column: Line { start: GridPlacement::<S>::Auto, end: GridPlacement::<S>::Auto },
672 };
673}
674
675impl<S: CheapCloneStr> Default for Style<S> {
676 fn default() -> Self {
677 Style::DEFAULT
678 }
679}
680
681impl<S: CheapCloneStr> CoreStyle for Style<S> {
682 type CustomIdent = S;
683
684 #[inline(always)]
685 fn box_generation_mode(&self) -> BoxGenerationMode {
686 match self.display {
687 Display::None => BoxGenerationMode::None,
688 _ => BoxGenerationMode::Normal,
689 }
690 }
691 #[inline(always)]
692 #[cfg(feature = "block_layout")]
693 fn is_block(&self) -> bool {
694 matches!(self.display, Display::Block)
695 }
696 #[inline(always)]
697 fn is_compressible_replaced(&self) -> bool {
698 self.item_is_replaced
699 }
700 #[inline(always)]
701 fn box_sizing(&self) -> BoxSizing {
702 self.box_sizing
703 }
704 #[inline(always)]
705 fn direction(&self) -> Direction {
706 self.direction
707 }
708 #[inline(always)]
709 fn overflow(&self) -> Point<Overflow> {
710 self.overflow
711 }
712 #[inline(always)]
713 fn scrollbar_width(&self) -> f32 {
714 self.scrollbar_width
715 }
716 #[inline(always)]
717 fn position(&self) -> Position {
718 self.position
719 }
720 #[inline(always)]
721 fn inset(&self) -> Rect<LengthPercentageAuto> {
722 self.inset
723 }
724 #[inline(always)]
725 fn size(&self) -> Size<Dimension> {
726 self.size
727 }
728 #[inline(always)]
729 fn min_size(&self) -> Size<Dimension> {
730 self.min_size
731 }
732 #[inline(always)]
733 fn max_size(&self) -> Size<Dimension> {
734 self.max_size
735 }
736 #[inline(always)]
737 fn aspect_ratio(&self) -> Option<f32> {
738 self.aspect_ratio
739 }
740 #[inline(always)]
741 fn margin(&self) -> Rect<LengthPercentageAuto> {
742 self.margin
743 }
744 #[inline(always)]
745 fn padding(&self) -> Rect<LengthPercentage> {
746 self.padding
747 }
748 #[inline(always)]
749 fn border(&self) -> Rect<LengthPercentage> {
750 self.border
751 }
752}
753
754impl<T: CoreStyle> CoreStyle for &'_ T {
755 type CustomIdent = T::CustomIdent;
756
757 #[inline(always)]
758 fn box_generation_mode(&self) -> BoxGenerationMode {
759 (*self).box_generation_mode()
760 }
761 #[inline(always)]
762 fn is_block(&self) -> bool {
763 (*self).is_block()
764 }
765 #[inline(always)]
766 fn is_compressible_replaced(&self) -> bool {
767 (*self).is_compressible_replaced()
768 }
769 #[inline(always)]
770 fn box_sizing(&self) -> BoxSizing {
771 (*self).box_sizing()
772 }
773 #[inline(always)]
774 fn direction(&self) -> Direction {
775 (*self).direction()
776 }
777 #[inline(always)]
778 fn overflow(&self) -> Point<Overflow> {
779 (*self).overflow()
780 }
781 #[inline(always)]
782 fn scrollbar_width(&self) -> f32 {
783 (*self).scrollbar_width()
784 }
785 #[inline(always)]
786 fn position(&self) -> Position {
787 (*self).position()
788 }
789 #[inline(always)]
790 fn inset(&self) -> Rect<LengthPercentageAuto> {
791 (*self).inset()
792 }
793 #[inline(always)]
794 fn size(&self) -> Size<Dimension> {
795 (*self).size()
796 }
797 #[inline(always)]
798 fn min_size(&self) -> Size<Dimension> {
799 (*self).min_size()
800 }
801 #[inline(always)]
802 fn max_size(&self) -> Size<Dimension> {
803 (*self).max_size()
804 }
805 #[inline(always)]
806 fn aspect_ratio(&self) -> Option<f32> {
807 (*self).aspect_ratio()
808 }
809 #[inline(always)]
810 fn margin(&self) -> Rect<LengthPercentageAuto> {
811 (*self).margin()
812 }
813 #[inline(always)]
814 fn padding(&self) -> Rect<LengthPercentage> {
815 (*self).padding()
816 }
817 #[inline(always)]
818 fn border(&self) -> Rect<LengthPercentage> {
819 (*self).border()
820 }
821}
822
823#[cfg(feature = "block_layout")]
824impl<S: CheapCloneStr> BlockContainerStyle for Style<S> {
825 #[inline(always)]
826 fn text_align(&self) -> TextAlign {
827 self.text_align
828 }
829
830 #[inline(always)]
831 fn align_content(&self) -> Option<AlignContent> {
832 self.align_content
833 }
834}
835
836#[cfg(feature = "block_layout")]
837impl<T: BlockContainerStyle> BlockContainerStyle for &'_ T {
838 #[inline(always)]
839 fn text_align(&self) -> TextAlign {
840 (*self).text_align()
841 }
842
843 #[inline(always)]
844 fn align_content(&self) -> Option<AlignContent> {
845 (*self).align_content()
846 }
847}
848
849#[cfg(feature = "block_layout")]
850impl<S: CheapCloneStr> BlockItemStyle for Style<S> {
851 #[inline(always)]
852 fn is_table(&self) -> bool {
853 self.item_is_table
854 }
855
856 #[cfg(feature = "float_layout")]
857 #[inline(always)]
858 fn float(&self) -> Float {
859 self.float
860 }
861
862 #[cfg(feature = "float_layout")]
863 #[inline(always)]
864 fn clear(&self) -> Clear {
865 self.clear
866 }
867}
868
869#[cfg(feature = "block_layout")]
870impl<T: BlockItemStyle> BlockItemStyle for &'_ T {
871 #[inline(always)]
872 fn is_table(&self) -> bool {
873 (*self).is_table()
874 }
875
876 #[cfg(feature = "float_layout")]
877 #[inline(always)]
878 fn float(&self) -> Float {
879 (*self).float()
880 }
881
882 #[cfg(feature = "float_layout")]
883 #[inline(always)]
884 fn clear(&self) -> Clear {
885 (*self).clear()
886 }
887}
888
889#[cfg(feature = "flexbox")]
890impl<S: CheapCloneStr> FlexboxContainerStyle for Style<S> {
891 #[inline(always)]
892 fn flex_direction(&self) -> FlexDirection {
893 self.flex_direction
894 }
895 #[inline(always)]
896 fn flex_wrap(&self) -> FlexWrap {
897 self.flex_wrap
898 }
899 #[inline(always)]
900 fn gap(&self) -> Size<LengthPercentage> {
901 self.gap
902 }
903 #[inline(always)]
904 fn align_content(&self) -> Option<AlignContent> {
905 self.align_content
906 }
907 #[inline(always)]
908 fn align_items(&self) -> Option<AlignItems> {
909 self.align_items
910 }
911 #[inline(always)]
912 fn justify_content(&self) -> Option<JustifyContent> {
913 self.justify_content
914 }
915}
916
917#[cfg(feature = "flexbox")]
918impl<T: FlexboxContainerStyle> FlexboxContainerStyle for &'_ T {
919 #[inline(always)]
920 fn flex_direction(&self) -> FlexDirection {
921 (*self).flex_direction()
922 }
923 #[inline(always)]
924 fn flex_wrap(&self) -> FlexWrap {
925 (*self).flex_wrap()
926 }
927 #[inline(always)]
928 fn gap(&self) -> Size<LengthPercentage> {
929 (*self).gap()
930 }
931 #[inline(always)]
932 fn align_content(&self) -> Option<AlignContent> {
933 (*self).align_content()
934 }
935 #[inline(always)]
936 fn align_items(&self) -> Option<AlignItems> {
937 (*self).align_items()
938 }
939 #[inline(always)]
940 fn justify_content(&self) -> Option<JustifyContent> {
941 (*self).justify_content()
942 }
943}
944
945#[cfg(feature = "flexbox")]
946impl<S: CheapCloneStr> FlexboxItemStyle for Style<S> {
947 #[inline(always)]
948 fn flex_basis(&self) -> Dimension {
949 self.flex_basis
950 }
951 #[inline(always)]
952 fn flex_grow(&self) -> f32 {
953 self.flex_grow
954 }
955 #[inline(always)]
956 fn flex_shrink(&self) -> f32 {
957 self.flex_shrink
958 }
959 #[inline(always)]
960 fn align_self(&self) -> Option<AlignSelf> {
961 self.align_self
962 }
963}
964
965#[cfg(feature = "flexbox")]
966impl<T: FlexboxItemStyle> FlexboxItemStyle for &'_ T {
967 #[inline(always)]
968 fn flex_basis(&self) -> Dimension {
969 (*self).flex_basis()
970 }
971 #[inline(always)]
972 fn flex_grow(&self) -> f32 {
973 (*self).flex_grow()
974 }
975 #[inline(always)]
976 fn flex_shrink(&self) -> f32 {
977 (*self).flex_shrink()
978 }
979 #[inline(always)]
980 fn align_self(&self) -> Option<AlignSelf> {
981 (*self).align_self()
982 }
983}
984
985#[cfg(feature = "grid")]
986impl<S: CheapCloneStr> GridContainerStyle for Style<S> {
987 type Repetition<'a>
988 = &'a GridTemplateRepetition<S>
989 where
990 Self: 'a;
991
992 type TemplateTrackList<'a>
993 = core::iter::Map<
994 core::slice::Iter<'a, GridTemplateComponent<S>>,
995 fn(&'a GridTemplateComponent<S>) -> GenericGridTemplateComponent<S, &'a GridTemplateRepetition<S>>,
996 >
997 where
998 Self: 'a;
999
1000 type AutoTrackList<'a>
1001 = core::iter::Copied<core::slice::Iter<'a, TrackSizingFunction>>
1002 where
1003 Self: 'a;
1004
1005 #[cfg(feature = "grid")]
1006 type TemplateLineNames<'a>
1007 = core::iter::Map<core::slice::Iter<'a, GridTrackVec<S>>, fn(&GridTrackVec<S>) -> core::slice::Iter<'_, S>>
1008 where
1009 Self: 'a;
1010 #[cfg(feature = "grid")]
1011 type GridTemplateAreas<'a>
1012 = core::iter::Cloned<core::slice::Iter<'a, GridTemplateArea<S>>>
1013 where
1014 Self: 'a;
1015
1016 #[inline(always)]
1017 fn grid_template_rows(&self) -> Option<Self::TemplateTrackList<'_>> {
1018 Some(self.grid_template_rows.iter().map(|c| c.as_component_ref()))
1019 }
1020 #[inline(always)]
1021 fn grid_template_columns(&self) -> Option<Self::TemplateTrackList<'_>> {
1022 Some(self.grid_template_columns.iter().map(|c| c.as_component_ref()))
1023 }
1024 #[inline(always)]
1025 fn grid_auto_rows(&self) -> Self::AutoTrackList<'_> {
1026 self.grid_auto_rows.iter().copied()
1027 }
1028 #[inline(always)]
1029 fn grid_auto_columns(&self) -> Self::AutoTrackList<'_> {
1030 self.grid_auto_columns.iter().copied()
1031 }
1032 #[inline(always)]
1033 fn grid_auto_flow(&self) -> GridAutoFlow {
1034 self.grid_auto_flow
1035 }
1036 #[inline(always)]
1037 fn gap(&self) -> Size<LengthPercentage> {
1038 self.gap
1039 }
1040 #[inline(always)]
1041 fn align_content(&self) -> Option<AlignContent> {
1042 self.align_content
1043 }
1044 #[inline(always)]
1045 fn justify_content(&self) -> Option<JustifyContent> {
1046 self.justify_content
1047 }
1048 #[inline(always)]
1049 fn align_items(&self) -> Option<AlignItems> {
1050 self.align_items
1051 }
1052 #[inline(always)]
1053 fn justify_items(&self) -> Option<AlignItems> {
1054 self.justify_items
1055 }
1056
1057 #[inline(always)]
1058 #[cfg(feature = "grid")]
1059 fn grid_template_areas(&self) -> Option<Self::GridTemplateAreas<'_>> {
1060 self.grid_template_areas.as_ref().map(|template| template.areas.iter().cloned())
1061 }
1062 #[inline(always)]
1063 #[cfg(feature = "grid")]
1064 fn grid_template_area_row_count(&self) -> u16 {
1065 self.grid_template_areas.as_ref().map(|template| template.row_count).unwrap_or(0)
1066 }
1067 #[inline(always)]
1068 #[cfg(feature = "grid")]
1069 fn grid_template_area_column_count(&self) -> u16 {
1070 self.grid_template_areas.as_ref().map(|template| template.column_count).unwrap_or(0)
1071 }
1072
1073 #[inline(always)]
1074 #[cfg(feature = "grid")]
1075 fn grid_template_column_names(&self) -> Option<Self::TemplateLineNames<'_>> {
1076 Some(self.grid_template_column_names.iter().map(|names| names.iter()))
1077 }
1078
1079 #[inline(always)]
1080 #[cfg(feature = "grid")]
1081 fn grid_template_row_names(&self) -> Option<Self::TemplateLineNames<'_>> {
1082 Some(self.grid_template_row_names.iter().map(|names| names.iter()))
1083 }
1084}
1085
1086#[cfg(feature = "grid")]
1087impl<T: GridContainerStyle> GridContainerStyle for &'_ T {
1088 type Repetition<'a>
1089 = T::Repetition<'a>
1090 where
1091 Self: 'a;
1092
1093 type TemplateTrackList<'a>
1094 = T::TemplateTrackList<'a>
1095 where
1096 Self: 'a;
1097
1098 type AutoTrackList<'a>
1099 = T::AutoTrackList<'a>
1100 where
1101 Self: 'a;
1102
1103 #[cfg(feature = "grid")]
1105 type TemplateLineNames<'a>
1106 = T::TemplateLineNames<'a>
1107 where
1108 Self: 'a;
1109 #[cfg(feature = "grid")]
1110 type GridTemplateAreas<'a>
1111 = T::GridTemplateAreas<'a>
1112 where
1113 Self: 'a;
1114
1115 #[inline(always)]
1116 fn grid_template_rows(&self) -> Option<Self::TemplateTrackList<'_>> {
1117 (*self).grid_template_rows()
1118 }
1119 #[inline(always)]
1120 fn grid_template_columns(&self) -> Option<Self::TemplateTrackList<'_>> {
1121 (*self).grid_template_columns()
1122 }
1123 #[inline(always)]
1124 fn grid_auto_rows(&self) -> Self::AutoTrackList<'_> {
1125 (*self).grid_auto_rows()
1126 }
1127 #[inline(always)]
1128 fn grid_auto_columns(&self) -> Self::AutoTrackList<'_> {
1129 (*self).grid_auto_columns()
1130 }
1131 #[cfg(feature = "grid")]
1132 #[inline(always)]
1133 fn grid_template_areas(&self) -> Option<Self::GridTemplateAreas<'_>> {
1134 (*self).grid_template_areas()
1135 }
1136 #[inline(always)]
1137 fn grid_template_area_row_count(&self) -> u16 {
1138 (*self).grid_template_area_row_count()
1139 }
1140 #[inline(always)]
1141 fn grid_template_area_column_count(&self) -> u16 {
1142 (*self).grid_template_area_column_count()
1143 }
1144 #[cfg(feature = "grid")]
1145 #[inline(always)]
1146 fn grid_template_column_names(&self) -> Option<Self::TemplateLineNames<'_>> {
1147 (*self).grid_template_column_names()
1148 }
1149 #[cfg(feature = "grid")]
1150 #[inline(always)]
1151 fn grid_template_row_names(&self) -> Option<Self::TemplateLineNames<'_>> {
1152 (*self).grid_template_row_names()
1153 }
1154 #[inline(always)]
1155 fn grid_auto_flow(&self) -> GridAutoFlow {
1156 (*self).grid_auto_flow()
1157 }
1158 #[inline(always)]
1159 fn gap(&self) -> Size<LengthPercentage> {
1160 (*self).gap()
1161 }
1162 #[inline(always)]
1163 fn align_content(&self) -> Option<AlignContent> {
1164 (*self).align_content()
1165 }
1166 #[inline(always)]
1167 fn justify_content(&self) -> Option<JustifyContent> {
1168 (*self).justify_content()
1169 }
1170 #[inline(always)]
1171 fn align_items(&self) -> Option<AlignItems> {
1172 (*self).align_items()
1173 }
1174 #[inline(always)]
1175 fn justify_items(&self) -> Option<AlignItems> {
1176 (*self).justify_items()
1177 }
1178}
1179
1180#[cfg(feature = "grid")]
1181impl<S: CheapCloneStr> GridItemStyle for Style<S> {
1182 #[inline(always)]
1183 fn grid_row(&self) -> Line<GridPlacement<S>> {
1184 self.grid_row.clone()
1186 }
1187 #[inline(always)]
1188 fn grid_column(&self) -> Line<GridPlacement<S>> {
1189 self.grid_column.clone()
1191 }
1192 #[inline(always)]
1193 fn align_self(&self) -> Option<AlignSelf> {
1194 self.align_self
1195 }
1196 #[inline(always)]
1197 fn justify_self(&self) -> Option<AlignSelf> {
1198 self.justify_self
1199 }
1200}
1201
1202#[cfg(feature = "grid")]
1203impl<T: GridItemStyle> GridItemStyle for &'_ T {
1204 #[inline(always)]
1205 fn grid_row(&self) -> Line<GridPlacement<Self::CustomIdent>> {
1206 (*self).grid_row()
1207 }
1208 #[inline(always)]
1209 fn grid_column(&self) -> Line<GridPlacement<Self::CustomIdent>> {
1210 (*self).grid_column()
1211 }
1212 #[inline(always)]
1213 fn align_self(&self) -> Option<AlignSelf> {
1214 (*self).align_self()
1215 }
1216 #[inline(always)]
1217 fn justify_self(&self) -> Option<AlignSelf> {
1218 (*self).justify_self()
1219 }
1220}
1221
1222#[cfg(test)]
1223mod tests {
1224 use std::sync::Arc;
1225
1226 use super::Style;
1227 use crate::sys::DefaultCheapStr;
1228 use crate::{geometry::*, style_helpers::TaffyAuto as _};
1229
1230 #[test]
1231 fn defaults_match() {
1232 #[cfg(feature = "grid")]
1233 use super::GridPlacement;
1234
1235 let old_defaults: Style<DefaultCheapStr> = Style {
1236 dummy: core::marker::PhantomData,
1237 display: Default::default(),
1238 item_is_table: false,
1239 item_is_replaced: false,
1240 box_sizing: Default::default(),
1241 #[cfg(feature = "float_layout")]
1242 float: Default::default(),
1243 #[cfg(feature = "float_layout")]
1244 clear: Default::default(),
1245 direction: Default::default(),
1246 overflow: Default::default(),
1247 scrollbar_width: 0.0,
1248 position: Default::default(),
1249 #[cfg(feature = "flexbox")]
1250 flex_direction: Default::default(),
1251 #[cfg(feature = "flexbox")]
1252 flex_wrap: Default::default(),
1253 #[cfg(any(feature = "flexbox", feature = "grid"))]
1254 align_items: Default::default(),
1255 #[cfg(any(feature = "flexbox", feature = "grid"))]
1256 align_self: Default::default(),
1257 #[cfg(feature = "grid")]
1258 justify_items: Default::default(),
1259 #[cfg(feature = "grid")]
1260 justify_self: Default::default(),
1261 #[cfg(any(feature = "flexbox", feature = "grid", feature = "block_layout"))]
1262 align_content: Default::default(),
1263 #[cfg(any(feature = "flexbox", feature = "grid"))]
1264 justify_content: Default::default(),
1265 inset: Rect::auto(),
1266 margin: Rect::zero(),
1267 padding: Rect::zero(),
1268 border: Rect::zero(),
1269 gap: Size::zero(),
1270 #[cfg(feature = "block_layout")]
1271 text_align: Default::default(),
1272 #[cfg(feature = "flexbox")]
1273 flex_grow: 0.0,
1274 #[cfg(feature = "flexbox")]
1275 flex_shrink: 1.0,
1276 #[cfg(feature = "flexbox")]
1277 flex_basis: super::Dimension::AUTO,
1278 size: Size::auto(),
1279 min_size: Size::auto(),
1280 max_size: Size::auto(),
1281 aspect_ratio: Default::default(),
1282 #[cfg(feature = "grid")]
1283 grid_template_rows: Default::default(),
1284 #[cfg(feature = "grid")]
1285 grid_template_columns: Default::default(),
1286 #[cfg(feature = "grid")]
1287 grid_template_row_names: Default::default(),
1288 #[cfg(feature = "grid")]
1289 grid_template_column_names: Default::default(),
1290 #[cfg(feature = "grid")]
1291 grid_template_areas: Default::default(),
1292 #[cfg(feature = "grid")]
1293 grid_auto_rows: Default::default(),
1294 #[cfg(feature = "grid")]
1295 grid_auto_columns: Default::default(),
1296 #[cfg(feature = "grid")]
1297 grid_auto_flow: Default::default(),
1298 #[cfg(feature = "grid")]
1299 grid_row: Line { start: GridPlacement::Auto, end: GridPlacement::Auto },
1300 #[cfg(feature = "grid")]
1301 grid_column: Line { start: GridPlacement::Auto, end: GridPlacement::Auto },
1302 };
1303
1304 assert_eq!(Style::DEFAULT, Style::<DefaultCheapStr>::default());
1305 assert_eq!(Style::DEFAULT, old_defaults);
1306 }
1307
1308 #[test]
1311 fn style_sizes() {
1312 use super::*;
1313 type S = crate::sys::DefaultCheapStr;
1314
1315 fn assert_type_size<T>(expected_size: usize) {
1316 let name = ::core::any::type_name::<T>();
1317 let name = name.replace("taffy::geometry::", "");
1318 let name = name.replace("taffy::style::dimension::", "");
1319 let name = name.replace("taffy::style::alignment::", "");
1320 let name = name.replace("taffy::style::flex::", "");
1321 let name = name.replace("taffy::style::grid::", "");
1322
1323 assert_eq!(
1324 ::core::mem::size_of::<T>(),
1325 expected_size,
1326 "Expected {} for be {} byte(s) but it was {} byte(s)",
1327 name,
1328 expected_size,
1329 ::core::mem::size_of::<T>(),
1330 );
1331 }
1332
1333 assert_type_size::<Display>(1);
1335 assert_type_size::<BoxSizing>(1);
1336 assert_type_size::<Position>(1);
1337 assert_type_size::<Overflow>(1);
1338
1339 assert_type_size::<f32>(4);
1341 assert_type_size::<LengthPercentage>(8);
1342 assert_type_size::<LengthPercentageAuto>(8);
1343 assert_type_size::<Dimension>(8);
1344 assert_type_size::<Size<LengthPercentage>>(16);
1345 assert_type_size::<Size<LengthPercentageAuto>>(16);
1346 assert_type_size::<Size<Dimension>>(16);
1347 assert_type_size::<Rect<LengthPercentage>>(32);
1348 assert_type_size::<Rect<LengthPercentageAuto>>(32);
1349 assert_type_size::<Rect<Dimension>>(32);
1350
1351 assert_type_size::<AlignContentKeyword>(1);
1355 assert_type_size::<AlignItemsKeyword>(1);
1356 assert_type_size::<AlignmentSafety>(1);
1357 assert_type_size::<AlignContent>(2);
1358 assert_type_size::<AlignItems>(2);
1359 assert_type_size::<Option<AlignItems>>(2);
1360 assert_type_size::<Option<AlignContent>>(2);
1361
1362 assert_type_size::<FlexDirection>(1);
1364 assert_type_size::<FlexWrap>(1);
1365
1366 assert_type_size::<GridAutoFlow>(1);
1368 assert_type_size::<MinTrackSizingFunction>(8);
1369 assert_type_size::<MaxTrackSizingFunction>(8);
1370 assert_type_size::<TrackSizingFunction>(16);
1371 assert_type_size::<Vec<TrackSizingFunction>>(24);
1372 assert_type_size::<Vec<GridTemplateComponent<S>>>(24);
1373
1374 assert_type_size::<GridTemplateComponent<String>>(56);
1376 assert_type_size::<GridPlacement<String>>(32);
1377 assert_type_size::<Line<GridPlacement<String>>>(64);
1378 assert_type_size::<Style<String>>(552);
1379
1380 assert_type_size::<GridTemplateComponent<Arc<str>>>(56);
1382 assert_type_size::<GridPlacement<Arc<str>>>(24);
1383 assert_type_size::<Line<GridPlacement<Arc<str>>>>(48);
1384 assert_type_size::<Style<Arc<str>>>(520);
1385 }
1386}