tawasuyu

tawasuyu/taffy

A high performance rust-powered UI layout library

Rust 583HTML 275Markdown 8TOML 41586 Sutichaykuna

⎇ 230ab9359bba75fdda0ff35319d082e79189046f src/style/mod.rs Rust · 1301 siq'ikuna · 44.4 KB Ñawpa willay Pi imata llamkarqan ch'uya

implement `direction` property 230ab9359 · Kane Wang ·

1//! A typed representation of [CSS style properties](https://css-tricks.com/snippets/css/a-guide-to-flexbox/) in Rust. Used as input to layout computation.
2mod 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, GridContainerStyle,
31    GridItemStyle, GridPlacement, GridTemplateComponent, GridTemplateRepetition, MaxTrackSizingFunction,
32    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/// Trait that represents a cheaply clonable string. If you're unsure what to use here
55/// consider `Arc<str>` or `string_cache::Atom`.
56#[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/// Trait that represents a cheaply clonable string. If you're unsure what to use here
68/// consider `Arc<str>` or `string_cache::Atom`.
69#[cfg(not(any(feature = "alloc", feature = "std")))]
70pub trait CheapCloneStr {}
71#[cfg(not(any(feature = "alloc", feature = "std")))]
72impl<T> CheapCloneStr for T {}
73
74/// The core set of styles that are shared between all CSS layout nodes
75///
76/// Note that all methods come with a default implementation which simply returns the default value for that style property
77/// but this is a just a convenience to save on boilerplate for styles that your implementation doesn't support. You will need
78/// to override the default implementation for each style property that your style type actually supports.
79pub trait CoreStyle {
80    /// The type of custom identifiers used to identify named grid lines and areas
81    type CustomIdent: CheapCloneStr;
82
83    /// Which box generation mode should be used
84    #[inline(always)]
85    fn box_generation_mode(&self) -> BoxGenerationMode {
86        BoxGenerationMode::DEFAULT
87    }
88    /// Is block layout?
89    #[inline(always)]
90    fn is_block(&self) -> bool {
91        false
92    }
93    /// Is it a compressible replaced element?
94    /// <https://drafts.csswg.org/css-sizing-3/#min-content-zero>
95    #[inline(always)]
96    fn is_compressible_replaced(&self) -> bool {
97        false
98    }
99    /// Which box do size styles apply to
100    #[inline(always)]
101    fn box_sizing(&self) -> BoxSizing {
102        BoxSizing::BorderBox
103    }
104
105    /// The direction of text, table and grid columns, and horizontal overflow.
106    #[inline(always)]
107    fn direction(&self) -> Direction {
108        Direction::Ltr
109    }
110
111    // Overflow properties
112    /// How children overflowing their container should affect layout
113    #[inline(always)]
114    fn overflow(&self) -> Point<Overflow> {
115        Style::<Self::CustomIdent>::DEFAULT.overflow
116    }
117    /// How much space (in points) should be reserved for the scrollbars of `Overflow::Scroll` and `Overflow::Auto` nodes.
118    #[inline(always)]
119    fn scrollbar_width(&self) -> f32 {
120        0.0
121    }
122
123    // Position properties
124    /// What should the `position` value of this struct use as a base offset?
125    #[inline(always)]
126    fn position(&self) -> Position {
127        Style::<Self::CustomIdent>::DEFAULT.position
128    }
129    /// How should the position of this element be tweaked relative to the layout defined?
130    #[inline(always)]
131    fn inset(&self) -> Rect<LengthPercentageAuto> {
132        Style::<Self::CustomIdent>::DEFAULT.inset
133    }
134
135    // Size properies
136    /// Sets the initial size of the item
137    #[inline(always)]
138    fn size(&self) -> Size<Dimension> {
139        Style::<Self::CustomIdent>::DEFAULT.size
140    }
141    /// Controls the minimum size of the item
142    #[inline(always)]
143    fn min_size(&self) -> Size<Dimension> {
144        Style::<Self::CustomIdent>::DEFAULT.min_size
145    }
146    /// Controls the maximum size of the item
147    #[inline(always)]
148    fn max_size(&self) -> Size<Dimension> {
149        Style::<Self::CustomIdent>::DEFAULT.max_size
150    }
151    /// Sets the preferred aspect ratio for the item
152    /// The ratio is calculated as width divided by height.
153    #[inline(always)]
154    fn aspect_ratio(&self) -> Option<f32> {
155        Style::<Self::CustomIdent>::DEFAULT.aspect_ratio
156    }
157
158    // Spacing Properties
159    /// How large should the margin be on each side?
160    #[inline(always)]
161    fn margin(&self) -> Rect<LengthPercentageAuto> {
162        Style::<Self::CustomIdent>::DEFAULT.margin
163    }
164    /// How large should the padding be on each side?
165    #[inline(always)]
166    fn padding(&self) -> Rect<LengthPercentage> {
167        Style::<Self::CustomIdent>::DEFAULT.padding
168    }
169    /// How large should the border be on each side?
170    #[inline(always)]
171    fn border(&self) -> Rect<LengthPercentage> {
172        Style::<Self::CustomIdent>::DEFAULT.border
173    }
174}
175
176/// Sets the layout used for the children of this node
177///
178/// The default values depends on on which feature flags are enabled. The order of precedence is: Flex, Grid, Block, None.
179#[derive(Copy, Clone, PartialEq, Eq, Debug)]
180#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
181pub enum Display {
182    /// The children will follow the block layout algorithm
183    #[cfg(feature = "block_layout")]
184    Block,
185    /// The children will follow the flexbox layout algorithm
186    #[cfg(feature = "flexbox")]
187    Flex,
188    /// The children will follow the CSS Grid layout algorithm
189    #[cfg(feature = "grid")]
190    Grid,
191    /// The node is hidden, and it's children will also be hidden
192    None,
193}
194
195impl Display {
196    /// The default Display mode
197    #[cfg(feature = "flexbox")]
198    pub const DEFAULT: Display = Display::Flex;
199
200    /// The default Display mode
201    #[cfg(all(feature = "grid", not(feature = "flexbox")))]
202    pub const DEFAULT: Display = Display::Grid;
203
204    /// The default Display mode
205    #[cfg(all(feature = "block_layout", not(feature = "flexbox"), not(feature = "grid")))]
206    pub const DEFAULT: Display = Display::Block;
207
208    /// The default Display mode
209    #[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
219impl core::fmt::Display for Display {
220    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
221        match self {
222            Display::None => write!(f, "NONE"),
223            #[cfg(feature = "block_layout")]
224            Display::Block => write!(f, "BLOCK"),
225            #[cfg(feature = "flexbox")]
226            Display::Flex => write!(f, "FLEX"),
227            #[cfg(feature = "grid")]
228            Display::Grid => write!(f, "GRID"),
229        }
230    }
231}
232
233/// An abstracted version of the CSS `display` property where any value other than "none" is represented by "normal"
234/// See: <https://www.w3.org/TR/css-display-3/#box-generation>
235#[derive(Copy, Clone, PartialEq, Eq, Debug)]
236#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
237pub enum BoxGenerationMode {
238    /// The node generates a box in the regular way
239    Normal,
240    /// The node and it's descendants generate no boxes (they are hidden)
241    None,
242}
243
244impl BoxGenerationMode {
245    /// The default of BoxGenerationMode
246    pub const DEFAULT: BoxGenerationMode = BoxGenerationMode::Normal;
247}
248
249impl Default for BoxGenerationMode {
250    fn default() -> Self {
251        Self::DEFAULT
252    }
253}
254
255/// The positioning strategy for this item.
256///
257/// This controls both how the origin is determined for the [`Style::position`] field,
258/// and whether or not the item will be controlled by flexbox's layout algorithm.
259///
260/// WARNING: this enum follows the behavior of [CSS's `position` property](https://developer.mozilla.org/en-US/docs/Web/CSS/position),
261/// which can be unintuitive.
262///
263/// [`Position::Relative`] is the default value, in contrast to the default behavior in CSS.
264#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)]
265#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
266pub enum Position {
267    /// The offset is computed relative to the final position given by the layout algorithm.
268    /// Offsets do not affect the position of any other items; they are effectively a correction factor applied at the end.
269    #[default]
270    Relative,
271    /// The offset is computed relative to this item's closest positioned ancestor, if any.
272    /// Otherwise, it is placed relative to the origin.
273    /// No space is created for the item in the page layout, and its size will not be altered.
274    ///
275    /// WARNING: to opt-out of layouting entirely, you must use [`Display::None`] instead on your [`Style`] object.
276    Absolute,
277}
278
279/// Specifies whether size styles for this node are assigned to the node's "content box" or "border box"
280///
281/// - The "content box" is the node's inner size excluding padding, border and margin
282/// - The "border box" is the node's outer size including padding and border (but still excluding margin)
283///
284/// This property modifies the application of the following styles:
285///
286///   - `size`
287///   - `min_size`
288///   - `max_size`
289///   - `flex_basis`
290///
291/// See <https://developer.mozilla.org/en-US/docs/Web/CSS/box-sizing>
292#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)]
293#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
294pub enum BoxSizing {
295    /// Size styles such size, min_size, max_size specify the box's "border box" (the size excluding margin but including padding/border)
296    #[default]
297    BorderBox,
298    /// Size styles such size, min_size, max_size specify the box's "content box" (the size excluding padding/border/margin)
299    ContentBox,
300}
301
302/// How children overflowing their container should affect layout
303///
304/// In CSS the primary effect of this property is to control whether contents of a parent container that overflow that container should
305/// be displayed anyway, be clipped, or trigger the container to become a scroll container. However it also has secondary effects on layout,
306/// the main ones being:
307///
308///   - The automatic minimum size Flexbox/CSS Grid items with non-`Visible` overflow is `0` rather than being content based
309///   - `Overflow::Scroll` nodes have space in the layout reserved for a scrollbar (width controlled by the `scrollbar_width` property)
310///
311/// In Taffy, we only implement the layout related secondary effects as we are not concerned with drawing/painting. The amount of space reserved for
312/// a scrollbar is controlled by the `scrollbar_width` property. If this is `0` then `Scroll` behaves identically to `Hidden`.
313///
314/// <https://developer.mozilla.org/en-US/docs/Web/CSS/overflow>
315#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)]
316#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
317pub enum Overflow {
318    /// The automatic minimum size of this node as a flexbox/grid item should be based on the size of its content.
319    /// Content that overflows this node *should* contribute to the scroll region of its parent.
320    #[default]
321    Visible,
322    /// The automatic minimum size of this node as a flexbox/grid item should be based on the size of its content.
323    /// Content that overflows this node should *not* contribute to the scroll region of its parent.
324    Clip,
325    /// The automatic minimum size of this node as a flexbox/grid item should be `0`.
326    /// Content that overflows this node should *not* contribute to the scroll region of its parent.
327    Hidden,
328    /// The automatic minimum size of this node as a flexbox/grid item should be `0`. Additionally, space should be reserved
329    /// for a scrollbar. The amount of space reserved is controlled by the `scrollbar_width` property.
330    /// Content that overflows this node should *not* contribute to the scroll region of its parent.
331    Scroll,
332}
333
334impl Overflow {
335    /// Returns true for overflow modes that contain their contents (`Overflow::Hidden`, `Overflow::Scroll`, `Overflow::Auto`)
336    /// or else false for overflow modes that allow their contains to spill (`Overflow::Visible`).
337    #[inline(always)]
338    pub fn is_scroll_container(self) -> bool {
339        match self {
340            Self::Visible | Self::Clip => false,
341            Self::Hidden | Self::Scroll => true,
342        }
343    }
344
345    /// Returns `Some(0.0)` if the overflow mode would cause the automatic minimum size of a Flexbox or CSS Grid item
346    /// to be `0`. Else returns None.
347    #[inline(always)]
348    pub(crate) fn maybe_into_automatic_min_size(self) -> Option<f32> {
349        match self.is_scroll_container() {
350            true => Some(0.0),
351            false => None,
352        }
353    }
354}
355
356/// Sets the direction of text, table and grid columns, and horizontal overflow.
357/// <https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/direction>
358#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)]
359#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
360pub enum Direction {
361    #[default]
362    /// Left-to-right
363    Ltr,
364    /// Right-to-left
365    Rtl,
366}
367
368impl Direction {
369    /// Returns true if the direction is right-to-left
370    #[inline]
371    pub(crate) fn is_rtl(&self) -> bool {
372        matches!(self, Direction::Rtl)
373    }
374}
375
376/// A typed representation of the CSS style information for a single node.
377///
378/// The most important idea in flexbox is the notion of a "main" and "cross" axis, which are always perpendicular to each other.
379/// The orientation of these axes are controlled via the [`FlexDirection`] field of this struct.
380///
381/// This struct follows the [CSS equivalent](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Basic_Concepts_of_Flexbox) directly;
382/// information about the behavior on the web should transfer directly.
383///
384/// Detailed information about the exact behavior of each of these fields
385/// can be found on [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS) by searching for the field name.
386/// The distinction between margin, padding and border is explained well in
387/// this [introduction to the box model](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Box_Model/Introduction_to_the_CSS_box_model).
388///
389/// If the behavior does not match the flexbox layout algorithm on the web, please file a bug!
390#[derive(Clone, PartialEq, Debug)]
391#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
392#[cfg_attr(feature = "serde", serde(default))]
393pub struct Style<S: CheapCloneStr = DefaultCheapStr> {
394    /// This is a dummy field which is necessary to make Taffy compile with the `grid` feature disabled
395    /// It should always be set to `core::marker::PhantomData`.
396    pub dummy: core::marker::PhantomData<S>,
397    /// What layout strategy should be used?
398    pub display: Display,
399    /// Whether a child is display:table or not. This affects children of block layouts.
400    /// This should really be part of `Display`, but it is currently seperate because table layout isn't implemented
401    pub item_is_table: bool,
402    /// Is it a replaced element like an image or form field?
403    /// <https://drafts.csswg.org/css-sizing-3/#min-content-zero>
404    pub item_is_replaced: bool,
405    /// Should size styles apply to the content box or the border box of the node
406    pub box_sizing: BoxSizing,
407    /// Sets the direction of text, table and grid columns, and horizontal overflow.
408    pub direction: Direction,
409
410    // Overflow properties
411    /// How children overflowing their container should affect layout
412    pub overflow: Point<Overflow>,
413    /// How much space (in points) should be reserved for the scrollbars of `Overflow::Scroll` and `Overflow::Auto` nodes.
414    pub scrollbar_width: f32,
415
416    #[cfg(feature = "float_layout")]
417    /// Should the box be floated
418    pub float: Float,
419    #[cfg(feature = "float_layout")]
420    /// Should the box clear floats
421    pub clear: Clear,
422
423    // Position properties
424    /// What should the `position` value of this struct use as a base offset?
425    pub position: Position,
426    /// How should the position of this element be tweaked relative to the layout defined?
427    #[cfg_attr(feature = "serde", serde(default = "style_helpers::auto"))]
428    pub inset: Rect<LengthPercentageAuto>,
429
430    // Size properties
431    /// Sets the initial size of the item
432    #[cfg_attr(feature = "serde", serde(default = "style_helpers::auto"))]
433    pub size: Size<Dimension>,
434    /// Controls the minimum size of the item
435    #[cfg_attr(feature = "serde", serde(default = "style_helpers::auto"))]
436    pub min_size: Size<Dimension>,
437    /// Controls the maximum size of the item
438    #[cfg_attr(feature = "serde", serde(default = "style_helpers::auto"))]
439    pub max_size: Size<Dimension>,
440    /// Sets the preferred aspect ratio for the item
441    ///
442    /// The ratio is calculated as width divided by height.
443    pub aspect_ratio: Option<f32>,
444
445    // Spacing Properties
446    /// How large should the margin be on each side?
447    #[cfg_attr(feature = "serde", serde(default = "style_helpers::zero"))]
448    pub margin: Rect<LengthPercentageAuto>,
449    /// How large should the padding be on each side?
450    #[cfg_attr(feature = "serde", serde(default = "style_helpers::zero"))]
451    pub padding: Rect<LengthPercentage>,
452    /// How large should the border be on each side?
453    #[cfg_attr(feature = "serde", serde(default = "style_helpers::zero"))]
454    pub border: Rect<LengthPercentage>,
455
456    // Alignment properties
457    /// How this node's children aligned in the cross/block axis?
458    #[cfg(any(feature = "flexbox", feature = "grid"))]
459    pub align_items: Option<AlignItems>,
460    /// How this node should be aligned in the cross/block axis
461    /// Falls back to the parents [`AlignItems`] if not set
462    #[cfg(any(feature = "flexbox", feature = "grid"))]
463    pub align_self: Option<AlignSelf>,
464    /// How this node's children should be aligned in the inline axis
465    #[cfg(feature = "grid")]
466    pub justify_items: Option<AlignItems>,
467    /// How this node should be aligned in the inline axis
468    /// Falls back to the parents [`JustifyItems`] if not set
469    #[cfg(feature = "grid")]
470    pub justify_self: Option<AlignSelf>,
471    /// How should content contained within this item be aligned in the cross/block axis
472    #[cfg(any(feature = "flexbox", feature = "grid"))]
473    pub align_content: Option<AlignContent>,
474    /// How should content contained within this item be aligned in the main/inline axis
475    #[cfg(any(feature = "flexbox", feature = "grid"))]
476    pub justify_content: Option<JustifyContent>,
477    /// How large should the gaps between items in a grid or flex container be?
478    #[cfg(any(feature = "flexbox", feature = "grid"))]
479    #[cfg_attr(feature = "serde", serde(default = "style_helpers::zero"))]
480    pub gap: Size<LengthPercentage>,
481
482    // Block container properties
483    /// How items elements should aligned in the inline axis
484    #[cfg(feature = "block_layout")]
485    pub text_align: TextAlign,
486
487    // Flexbox container properties
488    /// Which direction does the main axis flow in?
489    #[cfg(feature = "flexbox")]
490    pub flex_direction: FlexDirection,
491    /// Should elements wrap, or stay in a single line?
492    #[cfg(feature = "flexbox")]
493    pub flex_wrap: FlexWrap,
494
495    // Flexbox item properties
496    /// Sets the initial main axis size of the item
497    #[cfg(feature = "flexbox")]
498    pub flex_basis: Dimension,
499    /// The relative rate at which this item grows when it is expanding to fill space
500    ///
501    /// 0.0 is the default value, and this value must be positive.
502    #[cfg(feature = "flexbox")]
503    pub flex_grow: f32,
504    /// The relative rate at which this item shrinks when it is contracting to fit into space
505    ///
506    /// 1.0 is the default value, and this value must be positive.
507    #[cfg(feature = "flexbox")]
508    pub flex_shrink: f32,
509
510    // Grid container properies
511    /// Defines the track sizing functions (heights) of the grid rows
512    #[cfg(feature = "grid")]
513    pub grid_template_rows: GridTrackVec<GridTemplateComponent<S>>,
514    /// Defines the track sizing functions (widths) of the grid columns
515    #[cfg(feature = "grid")]
516    pub grid_template_columns: GridTrackVec<GridTemplateComponent<S>>,
517    /// Defines the size of implicitly created rows
518    #[cfg(feature = "grid")]
519    pub grid_auto_rows: GridTrackVec<TrackSizingFunction>,
520    /// Defined the size of implicitly created columns
521    #[cfg(feature = "grid")]
522    pub grid_auto_columns: GridTrackVec<TrackSizingFunction>,
523    /// Controls how items get placed into the grid for auto-placed items
524    #[cfg(feature = "grid")]
525    pub grid_auto_flow: GridAutoFlow,
526
527    // Grid container named properties
528    /// Defines the rectangular grid areas
529    #[cfg(feature = "grid")]
530    pub grid_template_areas: GridTrackVec<GridTemplateArea<S>>,
531    /// The named lines between the columns
532    #[cfg(feature = "grid")]
533    pub grid_template_column_names: GridTrackVec<GridTrackVec<S>>,
534    /// The named lines between the rows
535    #[cfg(feature = "grid")]
536    pub grid_template_row_names: GridTrackVec<GridTrackVec<S>>,
537
538    // Grid child properties
539    /// Defines which row in the grid the item should start and end at
540    #[cfg(feature = "grid")]
541    pub grid_row: Line<GridPlacement<S>>,
542    /// Defines which column in the grid the item should start and end at
543    #[cfg(feature = "grid")]
544    pub grid_column: Line<GridPlacement<S>>,
545}
546
547impl<S: CheapCloneStr> Style<S> {
548    /// The [`Default`] layout, in a form that can be used in const functions
549    pub const DEFAULT: Style<S> = Style {
550        dummy: core::marker::PhantomData,
551        display: Display::DEFAULT,
552        item_is_table: false,
553        item_is_replaced: false,
554        box_sizing: BoxSizing::BorderBox,
555        direction: Direction::Ltr,
556        overflow: Point { x: Overflow::Visible, y: Overflow::Visible },
557        scrollbar_width: 0.0,
558        #[cfg(feature = "float_layout")]
559        float: Float::None,
560        #[cfg(feature = "float_layout")]
561        clear: Clear::None,
562        position: Position::Relative,
563        inset: Rect::auto(),
564        margin: Rect::zero(),
565        padding: Rect::zero(),
566        border: Rect::zero(),
567        size: Size::auto(),
568        min_size: Size::auto(),
569        max_size: Size::auto(),
570        aspect_ratio: None,
571        #[cfg(any(feature = "flexbox", feature = "grid"))]
572        gap: Size::zero(),
573        // Alignment
574        #[cfg(any(feature = "flexbox", feature = "grid"))]
575        align_items: None,
576        #[cfg(any(feature = "flexbox", feature = "grid"))]
577        align_self: None,
578        #[cfg(feature = "grid")]
579        justify_items: None,
580        #[cfg(feature = "grid")]
581        justify_self: None,
582        #[cfg(any(feature = "flexbox", feature = "grid"))]
583        align_content: None,
584        #[cfg(any(feature = "flexbox", feature = "grid"))]
585        justify_content: None,
586        // Block
587        #[cfg(feature = "block_layout")]
588        text_align: TextAlign::Auto,
589        // Flexbox
590        #[cfg(feature = "flexbox")]
591        flex_direction: FlexDirection::Row,
592        #[cfg(feature = "flexbox")]
593        flex_wrap: FlexWrap::NoWrap,
594        #[cfg(feature = "flexbox")]
595        flex_grow: 0.0,
596        #[cfg(feature = "flexbox")]
597        flex_shrink: 1.0,
598        #[cfg(feature = "flexbox")]
599        flex_basis: Dimension::AUTO,
600        // Grid
601        #[cfg(feature = "grid")]
602        grid_template_rows: GridTrackVec::new(),
603        #[cfg(feature = "grid")]
604        grid_template_columns: GridTrackVec::new(),
605        #[cfg(feature = "grid")]
606        grid_template_areas: GridTrackVec::new(),
607        #[cfg(feature = "grid")]
608        grid_template_column_names: GridTrackVec::new(),
609        #[cfg(feature = "grid")]
610        grid_template_row_names: GridTrackVec::new(),
611        #[cfg(feature = "grid")]
612        grid_auto_rows: GridTrackVec::new(),
613        #[cfg(feature = "grid")]
614        grid_auto_columns: GridTrackVec::new(),
615        #[cfg(feature = "grid")]
616        grid_auto_flow: GridAutoFlow::Row,
617        #[cfg(feature = "grid")]
618        grid_row: Line { start: GridPlacement::<S>::Auto, end: GridPlacement::<S>::Auto },
619        #[cfg(feature = "grid")]
620        grid_column: Line { start: GridPlacement::<S>::Auto, end: GridPlacement::<S>::Auto },
621    };
622}
623
624impl<S: CheapCloneStr> Default for Style<S> {
625    fn default() -> Self {
626        Style::DEFAULT
627    }
628}
629
630impl<S: CheapCloneStr> CoreStyle for Style<S> {
631    type CustomIdent = S;
632
633    #[inline(always)]
634    fn box_generation_mode(&self) -> BoxGenerationMode {
635        match self.display {
636            Display::None => BoxGenerationMode::None,
637            _ => BoxGenerationMode::Normal,
638        }
639    }
640    #[inline(always)]
641    #[cfg(feature = "block_layout")]
642    fn is_block(&self) -> bool {
643        matches!(self.display, Display::Block)
644    }
645    #[inline(always)]
646    fn is_compressible_replaced(&self) -> bool {
647        self.item_is_replaced
648    }
649    #[inline(always)]
650    fn box_sizing(&self) -> BoxSizing {
651        self.box_sizing
652    }
653    #[inline(always)]
654    fn direction(&self) -> Direction {
655        self.direction
656    }
657    #[inline(always)]
658    fn overflow(&self) -> Point<Overflow> {
659        self.overflow
660    }
661    #[inline(always)]
662    fn scrollbar_width(&self) -> f32 {
663        self.scrollbar_width
664    }
665    #[inline(always)]
666    fn position(&self) -> Position {
667        self.position
668    }
669    #[inline(always)]
670    fn inset(&self) -> Rect<LengthPercentageAuto> {
671        self.inset
672    }
673    #[inline(always)]
674    fn size(&self) -> Size<Dimension> {
675        self.size
676    }
677    #[inline(always)]
678    fn min_size(&self) -> Size<Dimension> {
679        self.min_size
680    }
681    #[inline(always)]
682    fn max_size(&self) -> Size<Dimension> {
683        self.max_size
684    }
685    #[inline(always)]
686    fn aspect_ratio(&self) -> Option<f32> {
687        self.aspect_ratio
688    }
689    #[inline(always)]
690    fn margin(&self) -> Rect<LengthPercentageAuto> {
691        self.margin
692    }
693    #[inline(always)]
694    fn padding(&self) -> Rect<LengthPercentage> {
695        self.padding
696    }
697    #[inline(always)]
698    fn border(&self) -> Rect<LengthPercentage> {
699        self.border
700    }
701}
702
703impl<T: CoreStyle> CoreStyle for &'_ T {
704    type CustomIdent = T::CustomIdent;
705
706    #[inline(always)]
707    fn box_generation_mode(&self) -> BoxGenerationMode {
708        (*self).box_generation_mode()
709    }
710    #[inline(always)]
711    fn is_block(&self) -> bool {
712        (*self).is_block()
713    }
714    #[inline(always)]
715    fn is_compressible_replaced(&self) -> bool {
716        (*self).is_compressible_replaced()
717    }
718    #[inline(always)]
719    fn box_sizing(&self) -> BoxSizing {
720        (*self).box_sizing()
721    }
722    #[inline(always)]
723    fn direction(&self) -> Direction {
724        (*self).direction()
725    }
726    #[inline(always)]
727    fn overflow(&self) -> Point<Overflow> {
728        (*self).overflow()
729    }
730    #[inline(always)]
731    fn scrollbar_width(&self) -> f32 {
732        (*self).scrollbar_width()
733    }
734    #[inline(always)]
735    fn position(&self) -> Position {
736        (*self).position()
737    }
738    #[inline(always)]
739    fn inset(&self) -> Rect<LengthPercentageAuto> {
740        (*self).inset()
741    }
742    #[inline(always)]
743    fn size(&self) -> Size<Dimension> {
744        (*self).size()
745    }
746    #[inline(always)]
747    fn min_size(&self) -> Size<Dimension> {
748        (*self).min_size()
749    }
750    #[inline(always)]
751    fn max_size(&self) -> Size<Dimension> {
752        (*self).max_size()
753    }
754    #[inline(always)]
755    fn aspect_ratio(&self) -> Option<f32> {
756        (*self).aspect_ratio()
757    }
758    #[inline(always)]
759    fn margin(&self) -> Rect<LengthPercentageAuto> {
760        (*self).margin()
761    }
762    #[inline(always)]
763    fn padding(&self) -> Rect<LengthPercentage> {
764        (*self).padding()
765    }
766    #[inline(always)]
767    fn border(&self) -> Rect<LengthPercentage> {
768        (*self).border()
769    }
770}
771
772#[cfg(feature = "block_layout")]
773impl<S: CheapCloneStr> BlockContainerStyle for Style<S> {
774    #[inline(always)]
775    fn text_align(&self) -> TextAlign {
776        self.text_align
777    }
778}
779
780#[cfg(feature = "block_layout")]
781impl<T: BlockContainerStyle> BlockContainerStyle for &'_ T {
782    #[inline(always)]
783    fn text_align(&self) -> TextAlign {
784        (*self).text_align()
785    }
786}
787
788#[cfg(feature = "block_layout")]
789impl<S: CheapCloneStr> BlockItemStyle for Style<S> {
790    #[inline(always)]
791    fn is_table(&self) -> bool {
792        self.item_is_table
793    }
794
795    #[cfg(feature = "float_layout")]
796    #[inline(always)]
797    fn float(&self) -> Float {
798        self.float
799    }
800
801    #[cfg(feature = "float_layout")]
802    #[inline(always)]
803    fn clear(&self) -> Clear {
804        self.clear
805    }
806}
807
808#[cfg(feature = "block_layout")]
809impl<T: BlockItemStyle> BlockItemStyle for &'_ T {
810    #[inline(always)]
811    fn is_table(&self) -> bool {
812        (*self).is_table()
813    }
814
815    #[cfg(feature = "float_layout")]
816    #[inline(always)]
817    fn float(&self) -> Float {
818        (*self).float()
819    }
820
821    #[cfg(feature = "float_layout")]
822    #[inline(always)]
823    fn clear(&self) -> Clear {
824        (*self).clear()
825    }
826}
827
828#[cfg(feature = "flexbox")]
829impl<S: CheapCloneStr> FlexboxContainerStyle for Style<S> {
830    #[inline(always)]
831    fn flex_direction(&self) -> FlexDirection {
832        self.flex_direction
833    }
834    #[inline(always)]
835    fn flex_wrap(&self) -> FlexWrap {
836        self.flex_wrap
837    }
838    #[inline(always)]
839    fn gap(&self) -> Size<LengthPercentage> {
840        self.gap
841    }
842    #[inline(always)]
843    fn align_content(&self) -> Option<AlignContent> {
844        self.align_content
845    }
846    #[inline(always)]
847    fn align_items(&self) -> Option<AlignItems> {
848        self.align_items
849    }
850    #[inline(always)]
851    fn justify_content(&self) -> Option<JustifyContent> {
852        self.justify_content
853    }
854}
855
856#[cfg(feature = "flexbox")]
857impl<T: FlexboxContainerStyle> FlexboxContainerStyle for &'_ T {
858    #[inline(always)]
859    fn flex_direction(&self) -> FlexDirection {
860        (*self).flex_direction()
861    }
862    #[inline(always)]
863    fn flex_wrap(&self) -> FlexWrap {
864        (*self).flex_wrap()
865    }
866    #[inline(always)]
867    fn gap(&self) -> Size<LengthPercentage> {
868        (*self).gap()
869    }
870    #[inline(always)]
871    fn align_content(&self) -> Option<AlignContent> {
872        (*self).align_content()
873    }
874    #[inline(always)]
875    fn align_items(&self) -> Option<AlignItems> {
876        (*self).align_items()
877    }
878    #[inline(always)]
879    fn justify_content(&self) -> Option<JustifyContent> {
880        (*self).justify_content()
881    }
882}
883
884#[cfg(feature = "flexbox")]
885impl<S: CheapCloneStr> FlexboxItemStyle for Style<S> {
886    #[inline(always)]
887    fn flex_basis(&self) -> Dimension {
888        self.flex_basis
889    }
890    #[inline(always)]
891    fn flex_grow(&self) -> f32 {
892        self.flex_grow
893    }
894    #[inline(always)]
895    fn flex_shrink(&self) -> f32 {
896        self.flex_shrink
897    }
898    #[inline(always)]
899    fn align_self(&self) -> Option<AlignSelf> {
900        self.align_self
901    }
902}
903
904#[cfg(feature = "flexbox")]
905impl<T: FlexboxItemStyle> FlexboxItemStyle for &'_ T {
906    #[inline(always)]
907    fn flex_basis(&self) -> Dimension {
908        (*self).flex_basis()
909    }
910    #[inline(always)]
911    fn flex_grow(&self) -> f32 {
912        (*self).flex_grow()
913    }
914    #[inline(always)]
915    fn flex_shrink(&self) -> f32 {
916        (*self).flex_shrink()
917    }
918    #[inline(always)]
919    fn align_self(&self) -> Option<AlignSelf> {
920        (*self).align_self()
921    }
922}
923
924#[cfg(feature = "grid")]
925impl<S: CheapCloneStr> GridContainerStyle for Style<S> {
926    type Repetition<'a>
927        = &'a GridTemplateRepetition<S>
928    where
929        Self: 'a;
930
931    type TemplateTrackList<'a>
932        = core::iter::Map<
933        core::slice::Iter<'a, GridTemplateComponent<S>>,
934        fn(&'a GridTemplateComponent<S>) -> GenericGridTemplateComponent<S, &'a GridTemplateRepetition<S>>,
935    >
936    where
937        Self: 'a;
938
939    type AutoTrackList<'a>
940        = core::iter::Copied<core::slice::Iter<'a, TrackSizingFunction>>
941    where
942        Self: 'a;
943
944    #[cfg(feature = "grid")]
945    type TemplateLineNames<'a>
946        = core::iter::Map<core::slice::Iter<'a, GridTrackVec<S>>, fn(&GridTrackVec<S>) -> core::slice::Iter<'_, S>>
947    where
948        Self: 'a;
949    #[cfg(feature = "grid")]
950    type GridTemplateAreas<'a>
951        = core::iter::Cloned<core::slice::Iter<'a, GridTemplateArea<S>>>
952    where
953        Self: 'a;
954
955    #[inline(always)]
956    fn grid_template_rows(&self) -> Option<Self::TemplateTrackList<'_>> {
957        Some(self.grid_template_rows.iter().map(|c| c.as_component_ref()))
958    }
959    #[inline(always)]
960    fn grid_template_columns(&self) -> Option<Self::TemplateTrackList<'_>> {
961        Some(self.grid_template_columns.iter().map(|c| c.as_component_ref()))
962    }
963    #[inline(always)]
964    fn grid_auto_rows(&self) -> Self::AutoTrackList<'_> {
965        self.grid_auto_rows.iter().copied()
966    }
967    #[inline(always)]
968    fn grid_auto_columns(&self) -> Self::AutoTrackList<'_> {
969        self.grid_auto_columns.iter().copied()
970    }
971    #[inline(always)]
972    fn grid_auto_flow(&self) -> GridAutoFlow {
973        self.grid_auto_flow
974    }
975    #[inline(always)]
976    fn gap(&self) -> Size<LengthPercentage> {
977        self.gap
978    }
979    #[inline(always)]
980    fn align_content(&self) -> Option<AlignContent> {
981        self.align_content
982    }
983    #[inline(always)]
984    fn justify_content(&self) -> Option<JustifyContent> {
985        self.justify_content
986    }
987    #[inline(always)]
988    fn align_items(&self) -> Option<AlignItems> {
989        self.align_items
990    }
991    #[inline(always)]
992    fn justify_items(&self) -> Option<AlignItems> {
993        self.justify_items
994    }
995
996    #[inline(always)]
997    #[cfg(feature = "grid")]
998    fn grid_template_areas(&self) -> Option<Self::GridTemplateAreas<'_>> {
999        Some(self.grid_template_areas.iter().cloned())
1000    }
1001
1002    #[inline(always)]
1003    #[cfg(feature = "grid")]
1004    fn grid_template_column_names(&self) -> Option<Self::TemplateLineNames<'_>> {
1005        Some(self.grid_template_column_names.iter().map(|names| names.iter()))
1006    }
1007
1008    #[inline(always)]
1009    #[cfg(feature = "grid")]
1010    fn grid_template_row_names(&self) -> Option<Self::TemplateLineNames<'_>> {
1011        Some(self.grid_template_row_names.iter().map(|names| names.iter()))
1012    }
1013}
1014
1015#[cfg(feature = "grid")]
1016impl<T: GridContainerStyle> GridContainerStyle for &'_ T {
1017    type Repetition<'a>
1018        = T::Repetition<'a>
1019    where
1020        Self: 'a;
1021
1022    type TemplateTrackList<'a>
1023        = T::TemplateTrackList<'a>
1024    where
1025        Self: 'a;
1026
1027    type AutoTrackList<'a>
1028        = T::AutoTrackList<'a>
1029    where
1030        Self: 'a;
1031
1032    /// The type returned by grid_template_row_names and grid_template_column_names
1033    #[cfg(feature = "grid")]
1034    type TemplateLineNames<'a>
1035        = T::TemplateLineNames<'a>
1036    where
1037        Self: 'a;
1038    #[cfg(feature = "grid")]
1039    type GridTemplateAreas<'a>
1040        = T::GridTemplateAreas<'a>
1041    where
1042        Self: 'a;
1043
1044    #[inline(always)]
1045    fn grid_template_rows(&self) -> Option<Self::TemplateTrackList<'_>> {
1046        (*self).grid_template_rows()
1047    }
1048    #[inline(always)]
1049    fn grid_template_columns(&self) -> Option<Self::TemplateTrackList<'_>> {
1050        (*self).grid_template_columns()
1051    }
1052    #[inline(always)]
1053    fn grid_auto_rows(&self) -> Self::AutoTrackList<'_> {
1054        (*self).grid_auto_rows()
1055    }
1056    #[inline(always)]
1057    fn grid_auto_columns(&self) -> Self::AutoTrackList<'_> {
1058        (*self).grid_auto_columns()
1059    }
1060    #[cfg(feature = "grid")]
1061    #[inline(always)]
1062    fn grid_template_areas(&self) -> Option<Self::GridTemplateAreas<'_>> {
1063        (*self).grid_template_areas()
1064    }
1065    #[cfg(feature = "grid")]
1066    #[inline(always)]
1067    fn grid_template_column_names(&self) -> Option<Self::TemplateLineNames<'_>> {
1068        (*self).grid_template_column_names()
1069    }
1070    #[cfg(feature = "grid")]
1071    #[inline(always)]
1072    fn grid_template_row_names(&self) -> Option<Self::TemplateLineNames<'_>> {
1073        (*self).grid_template_row_names()
1074    }
1075    #[inline(always)]
1076    fn grid_auto_flow(&self) -> GridAutoFlow {
1077        (*self).grid_auto_flow()
1078    }
1079    #[inline(always)]
1080    fn gap(&self) -> Size<LengthPercentage> {
1081        (*self).gap()
1082    }
1083    #[inline(always)]
1084    fn align_content(&self) -> Option<AlignContent> {
1085        (*self).align_content()
1086    }
1087    #[inline(always)]
1088    fn justify_content(&self) -> Option<JustifyContent> {
1089        (*self).justify_content()
1090    }
1091    #[inline(always)]
1092    fn align_items(&self) -> Option<AlignItems> {
1093        (*self).align_items()
1094    }
1095    #[inline(always)]
1096    fn justify_items(&self) -> Option<AlignItems> {
1097        (*self).justify_items()
1098    }
1099}
1100
1101#[cfg(feature = "grid")]
1102impl<S: CheapCloneStr> GridItemStyle for Style<S> {
1103    #[inline(always)]
1104    fn grid_row(&self) -> Line<GridPlacement<S>> {
1105        // TODO: Investigate eliminating clone
1106        self.grid_row.clone()
1107    }
1108    #[inline(always)]
1109    fn grid_column(&self) -> Line<GridPlacement<S>> {
1110        // TODO: Investigate eliminating clone
1111        self.grid_column.clone()
1112    }
1113    #[inline(always)]
1114    fn align_self(&self) -> Option<AlignSelf> {
1115        self.align_self
1116    }
1117    #[inline(always)]
1118    fn justify_self(&self) -> Option<AlignSelf> {
1119        self.justify_self
1120    }
1121}
1122
1123#[cfg(feature = "grid")]
1124impl<T: GridItemStyle> GridItemStyle for &'_ T {
1125    #[inline(always)]
1126    fn grid_row(&self) -> Line<GridPlacement<Self::CustomIdent>> {
1127        (*self).grid_row()
1128    }
1129    #[inline(always)]
1130    fn grid_column(&self) -> Line<GridPlacement<Self::CustomIdent>> {
1131        (*self).grid_column()
1132    }
1133    #[inline(always)]
1134    fn align_self(&self) -> Option<AlignSelf> {
1135        (*self).align_self()
1136    }
1137    #[inline(always)]
1138    fn justify_self(&self) -> Option<AlignSelf> {
1139        (*self).justify_self()
1140    }
1141}
1142
1143#[cfg(test)]
1144mod tests {
1145    use std::sync::Arc;
1146
1147    use super::Style;
1148    use crate::sys::DefaultCheapStr;
1149    use crate::{geometry::*, style_helpers::TaffyAuto as _};
1150
1151    #[test]
1152    fn defaults_match() {
1153        #[cfg(feature = "grid")]
1154        use super::GridPlacement;
1155
1156        let old_defaults: Style<DefaultCheapStr> = Style {
1157            dummy: core::marker::PhantomData,
1158            display: Default::default(),
1159            item_is_table: false,
1160            item_is_replaced: false,
1161            box_sizing: Default::default(),
1162            #[cfg(feature = "float_layout")]
1163            float: Default::default(),
1164            #[cfg(feature = "float_layout")]
1165            clear: Default::default(),
1166            direction: Default::default(),
1167            overflow: Default::default(),
1168            scrollbar_width: 0.0,
1169            position: Default::default(),
1170            #[cfg(feature = "flexbox")]
1171            flex_direction: Default::default(),
1172            #[cfg(feature = "flexbox")]
1173            flex_wrap: Default::default(),
1174            #[cfg(any(feature = "flexbox", feature = "grid"))]
1175            align_items: Default::default(),
1176            #[cfg(any(feature = "flexbox", feature = "grid"))]
1177            align_self: Default::default(),
1178            #[cfg(feature = "grid")]
1179            justify_items: Default::default(),
1180            #[cfg(feature = "grid")]
1181            justify_self: Default::default(),
1182            #[cfg(any(feature = "flexbox", feature = "grid"))]
1183            align_content: Default::default(),
1184            #[cfg(any(feature = "flexbox", feature = "grid"))]
1185            justify_content: Default::default(),
1186            inset: Rect::auto(),
1187            margin: Rect::zero(),
1188            padding: Rect::zero(),
1189            border: Rect::zero(),
1190            gap: Size::zero(),
1191            #[cfg(feature = "block_layout")]
1192            text_align: Default::default(),
1193            #[cfg(feature = "flexbox")]
1194            flex_grow: 0.0,
1195            #[cfg(feature = "flexbox")]
1196            flex_shrink: 1.0,
1197            #[cfg(feature = "flexbox")]
1198            flex_basis: super::Dimension::AUTO,
1199            size: Size::auto(),
1200            min_size: Size::auto(),
1201            max_size: Size::auto(),
1202            aspect_ratio: Default::default(),
1203            #[cfg(feature = "grid")]
1204            grid_template_rows: Default::default(),
1205            #[cfg(feature = "grid")]
1206            grid_template_columns: Default::default(),
1207            #[cfg(feature = "grid")]
1208            grid_template_row_names: Default::default(),
1209            #[cfg(feature = "grid")]
1210            grid_template_column_names: Default::default(),
1211            #[cfg(feature = "grid")]
1212            grid_template_areas: Default::default(),
1213            #[cfg(feature = "grid")]
1214            grid_auto_rows: Default::default(),
1215            #[cfg(feature = "grid")]
1216            grid_auto_columns: Default::default(),
1217            #[cfg(feature = "grid")]
1218            grid_auto_flow: Default::default(),
1219            #[cfg(feature = "grid")]
1220            grid_row: Line { start: GridPlacement::Auto, end: GridPlacement::Auto },
1221            #[cfg(feature = "grid")]
1222            grid_column: Line { start: GridPlacement::Auto, end: GridPlacement::Auto },
1223        };
1224
1225        assert_eq!(Style::DEFAULT, Style::<DefaultCheapStr>::default());
1226        assert_eq!(Style::DEFAULT, old_defaults);
1227    }
1228
1229    // NOTE: Please feel free the update the sizes in this test as required. This test is here to prevent unintentional size changes
1230    // and to serve as accurate up-to-date documentation on the sizes.
1231    #[test]
1232    fn style_sizes() {
1233        use super::*;
1234        type S = crate::sys::DefaultCheapStr;
1235
1236        fn assert_type_size<T>(expected_size: usize) {
1237            let name = ::core::any::type_name::<T>();
1238            let name = name.replace("taffy::geometry::", "");
1239            let name = name.replace("taffy::style::dimension::", "");
1240            let name = name.replace("taffy::style::alignment::", "");
1241            let name = name.replace("taffy::style::flex::", "");
1242            let name = name.replace("taffy::style::grid::", "");
1243
1244            assert_eq!(
1245                ::core::mem::size_of::<T>(),
1246                expected_size,
1247                "Expected {} for be {} byte(s) but it was {} byte(s)",
1248                name,
1249                expected_size,
1250                ::core::mem::size_of::<T>(),
1251            );
1252        }
1253
1254        // Display and Position
1255        assert_type_size::<Display>(1);
1256        assert_type_size::<BoxSizing>(1);
1257        assert_type_size::<Position>(1);
1258        assert_type_size::<Overflow>(1);
1259
1260        // Dimensions and aggregations of Dimensions
1261        assert_type_size::<f32>(4);
1262        assert_type_size::<LengthPercentage>(8);
1263        assert_type_size::<LengthPercentageAuto>(8);
1264        assert_type_size::<Dimension>(8);
1265        assert_type_size::<Size<LengthPercentage>>(16);
1266        assert_type_size::<Size<LengthPercentageAuto>>(16);
1267        assert_type_size::<Size<Dimension>>(16);
1268        assert_type_size::<Rect<LengthPercentage>>(32);
1269        assert_type_size::<Rect<LengthPercentageAuto>>(32);
1270        assert_type_size::<Rect<Dimension>>(32);
1271
1272        // Alignment
1273        assert_type_size::<AlignContent>(1);
1274        assert_type_size::<AlignItems>(1);
1275        assert_type_size::<Option<AlignItems>>(1);
1276
1277        // Flexbox Container
1278        assert_type_size::<FlexDirection>(1);
1279        assert_type_size::<FlexWrap>(1);
1280
1281        // CSS Grid Container
1282        assert_type_size::<GridAutoFlow>(1);
1283        assert_type_size::<MinTrackSizingFunction>(8);
1284        assert_type_size::<MaxTrackSizingFunction>(8);
1285        assert_type_size::<TrackSizingFunction>(16);
1286        assert_type_size::<Vec<TrackSizingFunction>>(24);
1287        assert_type_size::<Vec<GridTemplateComponent<S>>>(24);
1288
1289        // String-type dependent (String)
1290        assert_type_size::<GridTemplateComponent<String>>(56);
1291        assert_type_size::<GridPlacement<String>>(32);
1292        assert_type_size::<Line<GridPlacement<String>>>(64);
1293        assert_type_size::<Style<String>>(536);
1294
1295        // String-type dependent (Arc<str>)
1296        assert_type_size::<GridTemplateComponent<Arc<str>>>(56);
1297        assert_type_size::<GridPlacement<Arc<str>>>(24);
1298        assert_type_size::<Line<GridPlacement<Arc<str>>>>(48);
1299        assert_type_size::<Style<Arc<str>>>(504);
1300    }
1301}