tawasuyu

tawasuyu/taffy

A high performance rust-powered UI layout library

Rust 859HTML 402Markdown 10TOML 52492 Definiciones

⎇ 7c123d3d5dffec52b7d432cbfdfd2b1ba6354040 src/style/mod.rs Rust · 1362 líneas · 45.9 KB Historia Quién tocó qué crudo

Units trait WIP 7c123d3d5 · Nico Burns ·

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