Move CompactLength into it's own module (#787)
1//! Style types for representing lengths / sizes
2use super::CompactLength;
3use crate::geometry::Rect;
4use crate::style_helpers::{FromLength, FromPercent, TaffyAuto, TaffyZero};
5
6/// A unit of linear measurement
7///
8/// This is commonly combined with [`Rect`], [`Point`](crate::geometry::Point) and [`Size<T>`](crate::geometry::Size).
9#[derive(Copy, Clone, PartialEq, Debug)]
10#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11pub struct LengthPercentage(pub(crate) CompactLength);
12impl TaffyZero for LengthPercentage {
13 const ZERO: Self = Self(CompactLength::ZERO);
14}
15impl FromLength for LengthPercentage {
16 fn from_length<Input: Into<f32> + Copy>(value: Input) -> Self {
17 Self(CompactLength::from_length(value))
18 }
19}
20impl FromPercent for LengthPercentage {
21 fn from_percent<Input: Into<f32> + Copy>(percent: Input) -> Self {
22 Self(CompactLength::from_percent(percent))
23 }
24}
25impl LengthPercentage {
26 /// Get the underlying `CompactLength` representation of the value
27 pub fn into_raw(self) -> CompactLength {
28 self.0
29 }
30
31 /// Create a LengthPercentage from a raw `CompactLength`.
32 /// # Safety
33 /// CompactLength must represent a valid variant for LengthPercentage
34 #[allow(unsafe_code)]
35 pub unsafe fn from_raw(val: CompactLength) -> Self {
36 Self(val)
37 }
38}
39
40/// A unit of linear measurement
41///
42/// This is commonly combined with [`Rect`], [`Point`](crate::geometry::Point) and [`Size<T>`](crate::geometry::Size).
43#[derive(Copy, Clone, PartialEq, Debug)]
44#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
45pub struct LengthPercentageAuto(pub(crate) CompactLength);
46impl TaffyZero for LengthPercentageAuto {
47 const ZERO: Self = Self(CompactLength::ZERO);
48}
49impl TaffyAuto for LengthPercentageAuto {
50 const AUTO: Self = Self(CompactLength::AUTO);
51}
52impl FromLength for LengthPercentageAuto {
53 fn from_length<Input: Into<f32> + Copy>(value: Input) -> Self {
54 Self(CompactLength::from_length(value))
55 }
56}
57impl FromPercent for LengthPercentageAuto {
58 fn from_percent<Input: Into<f32> + Copy>(percent: Input) -> Self {
59 Self(CompactLength::from_percent(percent))
60 }
61}
62impl From<LengthPercentage> for LengthPercentageAuto {
63 fn from(input: LengthPercentage) -> Self {
64 Self(input.0)
65 }
66}
67
68impl LengthPercentageAuto {
69 /// Returns:
70 /// - Some(length) for Length variants
71 /// - Some(resolved) using the provided context for Percent variants
72 /// - None for Auto variants
73 #[inline(always)]
74 pub fn resolve_to_option(self, context: f32, calc_resolver: impl Fn(u64, f32) -> f32) -> Option<f32> {
75 match self.0.tag() {
76 CompactLength::LENGTH_TAG => Some(self.0.value()),
77 CompactLength::PERCENT_TAG => Some(context * self.0.value()),
78 CompactLength::AUTO_TAG => None,
79 _ if self.0.is_calc() => Some(calc_resolver(self.0.calc_value(), context)),
80 _ => unreachable!("LengthPercentageAuto values cannot be constructed with other tags"),
81 }
82 }
83
84 /// Returns true if value is LengthPercentageAuto::Auto
85 #[inline(always)]
86 pub fn is_auto(self) -> bool {
87 self.0.is_auto()
88 }
89
90 /// Get the underlying `CompactLength` representation of the value
91 pub fn into_raw(self) -> CompactLength {
92 self.0
93 }
94
95 /// Create a LengthPercentageAuto from a raw `CompactLength`.
96 /// # Safety
97 /// CompactLength must represent a valid variant for LengthPercentageAuto
98 #[allow(unsafe_code)]
99 pub unsafe fn from_raw(val: CompactLength) -> Self {
100 Self(val)
101 }
102}
103
104/// A unit of linear measurement
105///
106/// This is commonly combined with [`Rect`], [`Point`](crate::geometry::Point) and [`Size<T>`](crate::geometry::Size).
107#[derive(Copy, Clone, PartialEq, Debug)]
108#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
109pub struct Dimension(pub(crate) CompactLength);
110impl TaffyZero for Dimension {
111 const ZERO: Self = Self(CompactLength::ZERO);
112}
113impl TaffyAuto for Dimension {
114 const AUTO: Self = Self(CompactLength::AUTO);
115}
116impl FromLength for Dimension {
117 fn from_length<Input: Into<f32> + Copy>(value: Input) -> Self {
118 Self(CompactLength::from_length(value))
119 }
120}
121impl FromPercent for Dimension {
122 fn from_percent<Input: Into<f32> + Copy>(percent: Input) -> Self {
123 Self(CompactLength::from_percent(percent))
124 }
125}
126impl From<LengthPercentage> for Dimension {
127 fn from(input: LengthPercentage) -> Self {
128 Self(input.0)
129 }
130}
131impl From<LengthPercentageAuto> for Dimension {
132 fn from(input: LengthPercentageAuto) -> Self {
133 Self(input.0)
134 }
135}
136
137impl Dimension {
138 /// Get Length value if value is Length variant
139 #[cfg(feature = "grid")]
140 pub fn into_option(self) -> Option<f32> {
141 match self.0.tag() {
142 CompactLength::LENGTH_TAG => Some(self.0.value()),
143 _ => None,
144 }
145 }
146 /// Returns true if value is Auto
147 #[inline(always)]
148 pub fn is_auto(self) -> bool {
149 self.0.is_auto()
150 }
151
152 /// Get the raw `CompactLength` tag
153 pub fn tag(self) -> u64 {
154 self.0.tag()
155 }
156
157 /// Get the raw `CompactLength` value for non-calc variants that have a numeric parameter
158 pub fn value(self) -> f32 {
159 self.0.value()
160 }
161
162 /// Get the underlying `CompactLength` representation of the value
163 pub fn into_raw(self) -> CompactLength {
164 self.0
165 }
166
167 /// Create a Dimension from a raw `CompactLength`.
168 /// # Safety
169 /// CompactLength must represent a valid variant for Dimension
170 #[allow(unsafe_code)]
171 pub unsafe fn from_raw(val: CompactLength) -> Self {
172 Self(val)
173 }
174}
175
176impl Rect<Dimension> {
177 /// Create a new Rect with length values
178 #[must_use]
179 pub const fn from_length(start: f32, end: f32, top: f32, bottom: f32) -> Self {
180 Rect {
181 left: Dimension(CompactLength::length(start)),
182 right: Dimension(CompactLength::length(end)),
183 top: Dimension(CompactLength::length(top)),
184 bottom: Dimension(CompactLength::length(bottom)),
185 }
186 }
187
188 /// Create a new Rect with percentage values
189 #[must_use]
190 pub const fn from_percent(start: f32, end: f32, top: f32, bottom: f32) -> Self {
191 Rect {
192 left: Dimension(CompactLength::percent(start)),
193 right: Dimension(CompactLength::percent(end)),
194 top: Dimension(CompactLength::percent(top)),
195 bottom: Dimension(CompactLength::percent(bottom)),
196 }
197 }
198}