diff --git a/src/compute/flexbox.rs b/src/compute/flexbox.rs index a418fb444b..5e1d10f6ff 100644 --- a/src/compute/flexbox.rs +++ b/src/compute/flexbox.rs @@ -367,10 +367,10 @@ fn compute_constants(style: &Style, node_size: Size>, parent_size: S width: node_size.width.maybe_sub(padding_border.horizontal_axis_sum()), height: node_size.height.maybe_sub(padding_border.vertical_axis_sum()), }; - let gap = style.gap.resolve_or_default(node_inner_size.or(Size { width: Some(0.0), height: Some(0.0) })); + let gap = style.gap.resolve_or_default(node_inner_size.or(Size::zero())); - let container_size = Size::ZERO; - let inner_container_size = Size::ZERO; + let container_size = Size::zero(); + let inner_container_size = Size::zero(); AlgoConstants { dir, @@ -413,10 +413,10 @@ fn generate_anonymous_flex_items(tree: &impl LayoutTree, node: Node, constants: violation: 0.0, frozen: false, - hypothetical_inner_size: Size::ZERO, - hypothetical_outer_size: Size::ZERO, - target_size: Size::ZERO, - outer_target_size: Size::ZERO, + hypothetical_inner_size: Size::zero(), + hypothetical_outer_size: Size::zero(), + target_size: Size::zero(), + outer_target_size: Size::zero(), baseline: 0.0, @@ -1020,7 +1020,7 @@ fn calculate_children_base_lines( &Layout { order: tree.children(node).position(|n| *n == child.node).unwrap() as u32, size: preliminary_size, - location: Point::ZERO, + location: Point::zero(), }, ); } @@ -1900,8 +1900,8 @@ mod tests { }; assert_eq!(constants.node_inner_size, inner_size); - assert_eq!(constants.container_size, Size::ZERO); - assert_eq!(constants.inner_container_size, Size::ZERO); + assert_eq!(constants.container_size, Size::zero()); + assert_eq!(constants.inner_container_size, Size::zero()); } #[test] @@ -1933,8 +1933,8 @@ mod tests { // all layouts should resolve to ZERO due to the root's DISPLAY::NONE for (node, _) in &taffy.nodes { if let Ok(layout) = taffy.layout(node) { - assert_eq!(layout.size, Size::ZERO); - assert_eq!(layout.location, Point::ZERO); + assert_eq!(layout.size, Size::zero()); + assert_eq!(layout.location, Point::zero()); } } } diff --git a/src/layout.rs b/src/layout.rs index 6d95995ce2..020b25af94 100644 --- a/src/layout.rs +++ b/src/layout.rs @@ -126,7 +126,7 @@ impl Layout { /// This means it should be rendered below all other [`Layout`]s. #[must_use] pub const fn new() -> Self { - Self { order: 0, size: Size::ZERO, location: Point::ZERO } + Self { order: 0, size: Size::zero(), location: Point::ZERO } } /// Creates a new zero-[`Layout`] with the supplied `order` value. @@ -135,7 +135,7 @@ impl Layout { /// The Zero-layout has size and location set to ZERO. #[must_use] pub const fn with_order(order: u32) -> Self { - Self { order, size: Size::ZERO, location: Point::ZERO } + Self { order, size: Size::zero(), location: Point::ZERO } } } diff --git a/src/lib.rs b/src/lib.rs index 80134e8d78..a04c80a385 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -27,6 +27,7 @@ pub mod math; pub mod node; pub mod prelude; pub mod style; +pub mod style_helpers; pub mod tree; #[cfg(feature = "random")] diff --git a/src/resolve.rs b/src/resolve.rs index 08f85c5d7d..687d644b4b 100644 --- a/src/resolve.rs +++ b/src/resolve.rs @@ -180,10 +180,10 @@ mod tests { /// /// The parent / context should not affect the outcome. #[rstest] - #[case(Size::AUTO, Size::NONE, Size::NONE)] - #[case(Size::AUTO, Size::new(5.0, 5.0), Size::NONE)] - #[case(Size::AUTO, Size::new(-5.0, -5.0), Size::NONE)] - #[case(Size::AUTO, Size::new(0.0, 0.0), Size::NONE)] + #[case(Size::auto(), Size::NONE, Size::NONE)] + #[case(Size::auto(), Size::new(5.0, 5.0), Size::NONE)] + #[case(Size::auto(), Size::new(-5.0, -5.0), Size::NONE)] + #[case(Size::auto(), Size::new(0.0, 0.0), Size::NONE)] fn maybe_resolve_auto( #[case] input: Size, #[case] context: Size>, @@ -274,10 +274,10 @@ mod tests { use rstest::rstest; #[rstest] - #[case(Rect::UNDEFINED, Size::NONE, Rect::ZERO)] - #[case(Rect::UNDEFINED, Size::new(5.0, 5.0), Rect::ZERO)] - #[case(Rect::UNDEFINED, Size::new(-5.0, -5.0), Rect::ZERO)] - #[case(Rect::UNDEFINED, Size::new(0.0, 0.0), Rect::ZERO)] + #[case(Rect::UNDEFINED, Size::NONE, Rect::zero())] + #[case(Rect::UNDEFINED, Size::new(5.0, 5.0), Rect::zero())] + #[case(Rect::UNDEFINED, Size::new(-5.0, -5.0), Rect::zero())] + #[case(Rect::UNDEFINED, Size::new(0.0, 0.0), Rect::zero())] fn resolve_or_default_undefined( #[case] input: Rect, #[case] context: Size>, @@ -287,10 +287,10 @@ mod tests { } #[rstest] - #[case(Rect::AUTO, Size::NONE, Rect::ZERO)] - #[case(Rect::AUTO, Size::new(5.0, 5.0), Rect::ZERO)] - #[case(Rect::AUTO, Size::new(-5.0, -5.0), Rect::ZERO)] - #[case(Rect::AUTO, Size::new(0.0, 0.0), Rect::ZERO)] + #[case(Rect::auto(), Size::NONE, Rect::zero())] + #[case(Rect::auto(), Size::new(5.0, 5.0), Rect::zero())] + #[case(Rect::auto(), Size::new(-5.0, -5.0), Rect::zero())] + #[case(Rect::auto(), Size::new(0.0, 0.0), Rect::zero())] fn resolve_or_default_auto( #[case] input: Rect, #[case] context: Size>, @@ -313,10 +313,10 @@ mod tests { } #[rstest] - #[case(Rect::from_percent(5.0, 5.0, 5.0, 5.0), Size::NONE, Rect::ZERO)] + #[case(Rect::from_percent(5.0, 5.0, 5.0, 5.0), Size::NONE, Rect::zero())] #[case(Rect::from_percent(5.0, 5.0, 5.0, 5.0), Size::new(5.0, 5.0), Rect::new(25.0, 25.0, 25.0, 25.0))] #[case(Rect::from_percent(5.0, 5.0, 5.0, 5.0), Size::new(-5.0, -5.0), Rect::new(-25.0, -25.0, -25.0, -25.0))] - #[case(Rect::from_percent(5.0, 5.0, 5.0, 5.0), Size::new(0.0, 0.0), Rect::ZERO)] + #[case(Rect::from_percent(5.0, 5.0, 5.0, 5.0), Size::new(0.0, 0.0), Rect::zero())] fn resolve_or_default_percent( #[case] input: Rect, #[case] context: Size>, @@ -333,10 +333,10 @@ mod tests { use rstest::rstest; #[rstest] - #[case(Rect::UNDEFINED, None, Rect::ZERO)] - #[case(Rect::UNDEFINED, Some(5.0), Rect::ZERO)] - #[case(Rect::UNDEFINED, Some(-5.0), Rect::ZERO)] - #[case(Rect::UNDEFINED, Some(0.0), Rect::ZERO)] + #[case(Rect::UNDEFINED, None, Rect::zero())] + #[case(Rect::UNDEFINED, Some(5.0), Rect::zero())] + #[case(Rect::UNDEFINED, Some(-5.0), Rect::zero())] + #[case(Rect::UNDEFINED, Some(0.0), Rect::zero())] fn resolve_or_default_undefined( #[case] input: Rect, #[case] context: Option, @@ -346,10 +346,10 @@ mod tests { } #[rstest] - #[case(Rect::AUTO, None, Rect::ZERO)] - #[case(Rect::AUTO, Some(5.0), Rect::ZERO)] - #[case(Rect::AUTO, Some(-5.0), Rect::ZERO)] - #[case(Rect::AUTO, Some(0.0), Rect::ZERO)] + #[case(Rect::auto(), None, Rect::zero())] + #[case(Rect::auto(), Some(5.0), Rect::zero())] + #[case(Rect::auto(), Some(-5.0), Rect::zero())] + #[case(Rect::auto(), Some(0.0), Rect::zero())] fn resolve_or_default_auto( #[case] input: Rect, #[case] context: Option, @@ -372,10 +372,10 @@ mod tests { } #[rstest] - #[case(Rect::from_percent(5.0, 5.0, 5.0, 5.0), None, Rect::ZERO)] + #[case(Rect::from_percent(5.0, 5.0, 5.0, 5.0), None, Rect::zero())] #[case(Rect::from_percent(5.0, 5.0, 5.0, 5.0), Some(5.0), Rect::new(25.0, 25.0, 25.0, 25.0))] #[case(Rect::from_percent(5.0, 5.0, 5.0, 5.0), Some(-5.0), Rect::new(-25.0, -25.0, -25.0, -25.0))] - #[case(Rect::from_percent(5.0, 5.0, 5.0, 5.0), Some(0.0), Rect::ZERO)] + #[case(Rect::from_percent(5.0, 5.0, 5.0, 5.0), Some(0.0), Rect::zero())] fn resolve_or_default_percent( #[case] input: Rect, #[case] context: Option, diff --git a/src/style.rs b/src/style.rs index 7b0b13491d..06b93544ca 100644 --- a/src/style.rs +++ b/src/style.rs @@ -445,9 +445,9 @@ impl Style { flex_grow: 0.0, flex_shrink: 1.0, flex_basis: Dimension::Auto, - size: Size::AUTO, - min_size: Size::AUTO, - max_size: Size::AUTO, + size: Size::auto(), + min_size: Size::auto(), + max_size: Size::auto(), aspect_ratio: None, }; } diff --git a/src/style_helpers.rs b/src/style_helpers.rs new file mode 100644 index 0000000000..6c6de21174 --- /dev/null +++ b/src/style_helpers.rs @@ -0,0 +1,168 @@ +//! Helper functions which it make it easier to create instances of types in the `style` and `geometry` modules. + +use crate::geometry::{Point, Rect, Size}; +use crate::style::Dimension; + +/// Returns the zero value for that type +pub const fn zero() -> T { + T::ZERO +} + +/// Trait to abstract over zero values +pub trait TaffyZero { + /// The zero value for type implementing TaffyZero + const ZERO: Self; +} +impl TaffyZero for f32 { + const ZERO: f32 = 0.0; +} +impl TaffyZero for Dimension { + const ZERO: Dimension = Dimension::Points(0.0); +} +impl TaffyZero for Option { + const ZERO: Option = Some(T::ZERO); +} +impl TaffyZero for Point { + const ZERO: Point = Point { x: T::ZERO, y: T::ZERO }; +} +impl Point { + /// Returns a Point where both the x and y values are the zero value of the contained type + /// (e.g. 0.0, Some(0.0), or Dimension::Points(0.0)) + pub const fn zero() -> Self { + zero::() + } +} +impl TaffyZero for Size { + const ZERO: Size = Size { width: T::ZERO, height: T::ZERO }; +} +impl Size { + /// Returns a Size where both the width and height values are the zero value of the contained type + /// (e.g. 0.0, Some(0.0), or Dimension::Points(0.0)) + pub const fn zero() -> Self { + zero::() + } +} +impl TaffyZero for Rect { + const ZERO: Rect = Rect { left: T::ZERO, right: T::ZERO, top: T::ZERO, bottom: T::ZERO }; +} +impl Rect { + /// Returns a Size where the left, right, top, and bottom values are all the zero value of the contained type + /// (e.g. 0.0, Some(0.0), or Dimension::Points(0.0)) + pub const fn zero() -> Self { + zero::() + } +} + +/// Returns the auto value for that type +pub const fn auto() -> T { + T::AUTO +} + +/// Trait to abstract over auto values +pub trait TaffyAuto { + /// The auto value for type implementing TaffyZero + const AUTO: Self; +} +impl TaffyAuto for Dimension { + const AUTO: Dimension = Dimension::Auto; +} +impl TaffyAuto for Option { + const AUTO: Option = Some(T::AUTO); +} +impl TaffyAuto for Point { + const AUTO: Point = Point { x: T::AUTO, y: T::AUTO }; +} +impl Point { + /// Returns a Point where both the x and y values are the auto value of the contained type + /// (e.g. Dimension::Auto or LengthPercentageAuto::Auto) + pub const fn auto() -> Self { + auto::() + } +} +impl TaffyAuto for Size { + const AUTO: Size = Size { width: T::AUTO, height: T::AUTO }; +} +impl Size { + /// Returns a Size where both the width and height values are the auto value of the contained type + /// (e.g. Dimension::Auto or LengthPercentageAuto::Auto) + pub const fn auto() -> Self { + auto::() + } +} +impl TaffyAuto for Rect { + const AUTO: Rect = Rect { left: T::AUTO, right: T::AUTO, top: T::AUTO, bottom: T::AUTO }; +} +impl Rect { + /// Returns a Size where the left, right, top, and bottom values are all the auto value of the contained type + /// (e.g. Dimension::Auto or LengthPercentageAuto::Auto) + pub const fn auto() -> Self { + auto::() + } +} + +/// Returns a value of the inferred type which represent a constant of points +pub fn points + Copy, T: FromPoints>(points: Input) -> T { + T::from_points(points) +} + +/// Trait to create constant points values from plain numbers +pub trait FromPoints { + /// Converts into an Into into Self + fn from_points + Copy>(points: Input) -> Self; +} +impl FromPoints for f32 { + fn from_points + Copy>(points: Input) -> Self { + points.into() + } +} +impl FromPoints for Option { + fn from_points + Copy>(points: Input) -> Self { + Some(points.into()) + } +} +impl FromPoints for Dimension { + fn from_points + Copy>(points: Input) -> Self { + Dimension::Points(points.into()) + } +} +impl FromPoints for Point { + fn from_points + Copy>(points: Input) -> Self { + Point { x: T::from_points(points.into()), y: T::from_points(points.into()) } + } +} +impl Point { + /// Returns a Point where both the x and y values are the constant points value of the contained type + /// (e.g. 2.1, Some(2.1), or Dimension::Points(2.1)) + pub fn points + Copy>(points_value: Input) -> Self { + points::(points_value) + } +} +impl FromPoints for Size { + fn from_points + Copy>(points: Input) -> Self { + Size { width: T::from_points(points.into()), height: T::from_points(points.into()) } + } +} +impl Size { + /// Returns a Size where both the width and height values are the constant points value of the contained type + /// (e.g. 2.1, Some(2.1), or Dimension::Points(2.1)) + pub fn points + Copy>(points_value: Input) -> Self { + points::(points_value) + } +} +impl FromPoints for Rect { + fn from_points + Copy>(points: Input) -> Self { + Rect { + left: T::from_points(points.into()), + right: T::from_points(points.into()), + top: T::from_points(points.into()), + bottom: T::from_points(points.into()), + } + } +} +impl Rect { + /// Returns a Rect where the left, right, top and bottom values are all constant points value of the contained type + /// (e.g. 2.1, Some(2.1), or Dimension::Points(2.1)) + pub fn points + Copy>(points_value: Input) -> Self { + points::(points_value) + } +}