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