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}