• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! Helper functions which it make it easier to create instances of types in the `style` and `geometry` modules.
2 use crate::{
3     geometry::{Line, Point, Rect, Size},
4     style::LengthPercentage,
5 };
6 
7 #[cfg(feature = "grid")]
8 use crate::{
9     geometry::MinMax,
10     style::{
11         GridTrackRepetition, MaxTrackSizingFunction, MinTrackSizingFunction, NonRepeatedTrackSizingFunction,
12         TrackSizingFunction,
13     },
14     util::sys::Vec,
15 };
16 #[cfg(feature = "grid")]
17 use core::fmt::Debug;
18 
19 /// Returns an auto-repeated track definition
20 #[cfg(feature = "grid")]
repeat<Input>(repetition_kind: Input, track_list: Vec<NonRepeatedTrackSizingFunction>) -> TrackSizingFunction where Input: TryInto<GridTrackRepetition>, <Input as TryInto<GridTrackRepetition>>::Error: Debug,21 pub fn repeat<Input>(repetition_kind: Input, track_list: Vec<NonRepeatedTrackSizingFunction>) -> TrackSizingFunction
22 where
23     Input: TryInto<GridTrackRepetition>,
24     <Input as TryInto<GridTrackRepetition>>::Error: Debug,
25 {
26     TrackSizingFunction::Repeat(repetition_kind.try_into().unwrap(), track_list)
27 }
28 
29 #[cfg(feature = "grid")]
30 /// Returns a grid template containing `count` evenly sized tracks
evenly_sized_tracks(count: u16) -> Vec<TrackSizingFunction>31 pub fn evenly_sized_tracks(count: u16) -> Vec<TrackSizingFunction> {
32     use crate::util::sys::new_vec_with_capacity;
33     let mut repeated_tracks = new_vec_with_capacity(1);
34     repeated_tracks.push(flex(1.0f32));
35     let mut tracks = new_vec_with_capacity(1);
36     tracks.push(repeat(count, repeated_tracks));
37     tracks
38 }
39 
40 /// Specifies a grid line to place a grid item between in CSS Grid Line coordinates:
41 ///  - Positive indices count upwards from the start (top or left) of the explicit grid
42 ///  - Negative indices count downwards from the end (bottom or right) of the explicit grid
43 ///  - ZERO IS INVALID index, and will be treated as a GridPlacement::Auto.
line<T: TaffyGridLine>(index: i16) -> T44 pub fn line<T: TaffyGridLine>(index: i16) -> T {
45     T::from_line_index(index)
46 }
47 /// Trait to abstract over grid line values
48 pub trait TaffyGridLine {
49     /// Converts an i16 into Self
from_line_index(index: i16) -> Self50     fn from_line_index(index: i16) -> Self;
51 }
52 
53 /// Returns a GridPlacement::Span
span<T: TaffyGridSpan>(span: u16) -> T54 pub fn span<T: TaffyGridSpan>(span: u16) -> T {
55     T::from_span(span)
56 }
57 /// Trait to abstract over grid span values
58 pub trait TaffyGridSpan {
59     /// Converts an iu6 into Self
from_span(span: u16) -> Self60     fn from_span(span: u16) -> Self;
61 }
62 
63 /// Returns a MinMax with min value of min and max value of max
64 #[cfg(feature = "grid")]
minmax<Output>(min: MinTrackSizingFunction, max: MaxTrackSizingFunction) -> Output where Output: From<MinMax<MinTrackSizingFunction, MaxTrackSizingFunction>>,65 pub fn minmax<Output>(min: MinTrackSizingFunction, max: MaxTrackSizingFunction) -> Output
66 where
67     Output: From<MinMax<MinTrackSizingFunction, MaxTrackSizingFunction>>,
68 {
69     MinMax { min, max }.into()
70 }
71 
72 /// Shorthand for minmax(0, Nfr). Probably what you want if you want exactly evenly sized tracks.
73 #[cfg(feature = "grid")]
flex<Input, Output>(flex_fraction: Input) -> Output where Input: Into<f32> + Copy, Output: From<MinMax<MinTrackSizingFunction, MaxTrackSizingFunction>>,74 pub fn flex<Input, Output>(flex_fraction: Input) -> Output
75 where
76     Input: Into<f32> + Copy,
77     Output: From<MinMax<MinTrackSizingFunction, MaxTrackSizingFunction>>,
78 {
79     MinMax { min: zero(), max: fr(flex_fraction.into()) }.into()
80 }
81 
82 /// Returns the zero value for that type
zero<T: TaffyZero>() -> T83 pub const fn zero<T: TaffyZero>() -> T {
84     T::ZERO
85 }
86 
87 /// Trait to abstract over zero values
88 pub trait TaffyZero {
89     /// The zero value for type implementing TaffyZero
90     const ZERO: Self;
91 }
92 impl TaffyZero for f32 {
93     const ZERO: f32 = 0.0;
94 }
95 impl<T: TaffyZero> TaffyZero for Option<T> {
96     const ZERO: Option<T> = Some(T::ZERO);
97 }
98 impl<T: TaffyZero> TaffyZero for Point<T> {
99     const ZERO: Point<T> = Point { x: T::ZERO, y: T::ZERO };
100 }
101 impl<T: TaffyZero> Point<T> {
102     /// Returns a Point where both the x and y values are the zero value of the contained type
103     /// (e.g. 0.0, Some(0.0), or Dimension::Length(0.0))
zero() -> Self104     pub const fn zero() -> Self {
105         zero::<Self>()
106     }
107 }
108 impl<T: TaffyZero> TaffyZero for Line<T> {
109     const ZERO: Line<T> = Line { start: T::ZERO, end: T::ZERO };
110 }
111 impl<T: TaffyZero> Line<T> {
112     /// Returns a Line where both the start and end values are the zero value of the contained type
113     /// (e.g. 0.0, Some(0.0), or Dimension::Length(0.0))
zero() -> Self114     pub const fn zero() -> Self {
115         zero::<Self>()
116     }
117 }
118 impl<T: TaffyZero> TaffyZero for Size<T> {
119     const ZERO: Size<T> = Size { width: T::ZERO, height: T::ZERO };
120 }
121 impl<T: TaffyZero> Size<T> {
122     /// Returns a Size where both the width and height values are the zero value of the contained type
123     /// (e.g. 0.0, Some(0.0), or Dimension::Length(0.0))
zero() -> Self124     pub const fn zero() -> Self {
125         zero::<Self>()
126     }
127 }
128 impl<T: TaffyZero> TaffyZero for Rect<T> {
129     const ZERO: Rect<T> = Rect { left: T::ZERO, right: T::ZERO, top: T::ZERO, bottom: T::ZERO };
130 }
131 impl<T: TaffyZero> Rect<T> {
132     /// Returns a Rect where the left, right, top, and bottom values are all the zero value of the contained type
133     /// (e.g. 0.0, Some(0.0), or Dimension::Length(0.0))
zero() -> Self134     pub const fn zero() -> Self {
135         zero::<Self>()
136     }
137 }
138 
139 /// Returns the auto value for that type
auto<T: TaffyAuto>() -> T140 pub const fn auto<T: TaffyAuto>() -> T {
141     T::AUTO
142 }
143 
144 /// Trait to abstract over auto values
145 pub trait TaffyAuto {
146     /// The auto value for type implementing TaffyAuto
147     const AUTO: Self;
148 }
149 impl<T: TaffyAuto> TaffyAuto for Option<T> {
150     const AUTO: Option<T> = Some(T::AUTO);
151 }
152 impl<T: TaffyAuto> TaffyAuto for Point<T> {
153     const AUTO: Point<T> = Point { x: T::AUTO, y: T::AUTO };
154 }
155 impl<T: TaffyAuto> Point<T> {
156     /// Returns a Point where both the x and y values are the auto value of the contained type
157     /// (e.g. Dimension::Auto or LengthPercentageAuto::Auto)
auto() -> Self158     pub const fn auto() -> Self {
159         auto::<Self>()
160     }
161 }
162 impl<T: TaffyAuto> TaffyAuto for Line<T> {
163     const AUTO: Line<T> = Line { start: T::AUTO, end: T::AUTO };
164 }
165 impl<T: TaffyAuto> Line<T> {
166     /// Returns a Line where both the start and end values are the auto value of the contained type
167     /// (e.g. Dimension::Auto or LengthPercentageAuto::Auto)
auto() -> Self168     pub const fn auto() -> Self {
169         auto::<Self>()
170     }
171 }
172 impl<T: TaffyAuto> TaffyAuto for Size<T> {
173     const AUTO: Size<T> = Size { width: T::AUTO, height: T::AUTO };
174 }
175 impl<T: TaffyAuto> Size<T> {
176     /// Returns a Size where both the width and height values are the auto value of the contained type
177     /// (e.g. Dimension::Auto or LengthPercentageAuto::Auto)
auto() -> Self178     pub const fn auto() -> Self {
179         auto::<Self>()
180     }
181 }
182 impl<T: TaffyAuto> TaffyAuto for Rect<T> {
183     const AUTO: Rect<T> = Rect { left: T::AUTO, right: T::AUTO, top: T::AUTO, bottom: T::AUTO };
184 }
185 impl<T: TaffyAuto> Rect<T> {
186     /// Returns a Rect where the left, right, top, and bottom values are all the auto value of the contained type
187     /// (e.g. Dimension::Auto or LengthPercentageAuto::Auto)
auto() -> Self188     pub const fn auto() -> Self {
189         auto::<Self>()
190     }
191 }
192 
193 /// Returns the auto value for that type
min_content<T: TaffyMinContent>() -> T194 pub const fn min_content<T: TaffyMinContent>() -> T {
195     T::MIN_CONTENT
196 }
197 
198 /// Trait to abstract over min_content values
199 pub trait TaffyMinContent {
200     /// The min_content value for type implementing TaffyZero
201     const MIN_CONTENT: Self;
202 }
203 impl<T: TaffyMinContent> TaffyMinContent for Option<T> {
204     const MIN_CONTENT: Option<T> = Some(T::MIN_CONTENT);
205 }
206 impl<T: TaffyMinContent> TaffyMinContent for Point<T> {
207     const MIN_CONTENT: Point<T> = Point { x: T::MIN_CONTENT, y: T::MIN_CONTENT };
208 }
209 impl<T: TaffyMinContent> Point<T> {
210     /// Returns a Point where both the x and y values are the min_content value of the contained type
211     /// (e.g. Dimension::Auto or LengthPercentageAuto::Auto)
min_content() -> Self212     pub const fn min_content() -> Self {
213         min_content::<Self>()
214     }
215 }
216 impl<T: TaffyMinContent> TaffyMinContent for Line<T> {
217     const MIN_CONTENT: Line<T> = Line { start: T::MIN_CONTENT, end: T::MIN_CONTENT };
218 }
219 impl<T: TaffyMinContent> Line<T> {
220     /// Returns a Line where both the start and end values are the min_content value of the contained type
221     /// (e.g. Dimension::Auto or LengthPercentageAuto::Auto)
min_content() -> Self222     pub const fn min_content() -> Self {
223         min_content::<Self>()
224     }
225 }
226 impl<T: TaffyMinContent> TaffyMinContent for Size<T> {
227     const MIN_CONTENT: Size<T> = Size { width: T::MIN_CONTENT, height: T::MIN_CONTENT };
228 }
229 impl<T: TaffyMinContent> Size<T> {
230     /// Returns a Size where both the width and height values are the min_content value of the contained type
231     /// (e.g. Dimension::Auto or LengthPercentageAuto::Auto)
min_content() -> Self232     pub const fn min_content() -> Self {
233         min_content::<Self>()
234     }
235 }
236 impl<T: TaffyMinContent> TaffyMinContent for Rect<T> {
237     const MIN_CONTENT: Rect<T> =
238         Rect { left: T::MIN_CONTENT, right: T::MIN_CONTENT, top: T::MIN_CONTENT, bottom: T::MIN_CONTENT };
239 }
240 impl<T: TaffyMinContent> Rect<T> {
241     /// Returns a Rect where the left, right, top, and bottom values are all the min_content value of the contained type
242     /// (e.g. Dimension::Auto or LengthPercentageAuto::Auto)
min_content() -> Self243     pub const fn min_content() -> Self {
244         min_content::<Self>()
245     }
246 }
247 
248 /// Returns the auto value for that type
max_content<T: TaffyMaxContent>() -> T249 pub const fn max_content<T: TaffyMaxContent>() -> T {
250     T::MAX_CONTENT
251 }
252 
253 /// Trait to abstract over max_content values
254 pub trait TaffyMaxContent {
255     /// The max_content value for type implementing TaffyZero
256     const MAX_CONTENT: Self;
257 }
258 impl<T: TaffyMaxContent> TaffyMaxContent for Option<T> {
259     const MAX_CONTENT: Option<T> = Some(T::MAX_CONTENT);
260 }
261 impl<T: TaffyMaxContent> TaffyMaxContent for Point<T> {
262     const MAX_CONTENT: Point<T> = Point { x: T::MAX_CONTENT, y: T::MAX_CONTENT };
263 }
264 impl<T: TaffyMaxContent> Point<T> {
265     /// Returns a Point where both the x and y values are the max_content value of the contained type
266     /// (e.g. Dimension::Auto or LengthPercentageAuto::Auto)
max_content() -> Self267     pub const fn max_content() -> Self {
268         max_content::<Self>()
269     }
270 }
271 impl<T: TaffyMaxContent> TaffyMaxContent for Line<T> {
272     const MAX_CONTENT: Line<T> = Line { start: T::MAX_CONTENT, end: T::MAX_CONTENT };
273 }
274 impl<T: TaffyMaxContent> Line<T> {
275     /// Returns a Line where both the start and end values are the max_content value of the contained type
276     /// (e.g. Dimension::Auto or LengthPercentageAuto::Auto)
max_content() -> Self277     pub const fn max_content() -> Self {
278         max_content::<Self>()
279     }
280 }
281 impl<T: TaffyMaxContent> TaffyMaxContent for Size<T> {
282     const MAX_CONTENT: Size<T> = Size { width: T::MAX_CONTENT, height: T::MAX_CONTENT };
283 }
284 impl<T: TaffyMaxContent> Size<T> {
285     /// Returns a Size where both the width and height values are the max_content value of the contained type
286     /// (e.g. Dimension::Auto or LengthPercentageAuto::Auto)
max_content() -> Self287     pub const fn max_content() -> Self {
288         max_content::<Self>()
289     }
290 }
291 impl<T: TaffyMaxContent> TaffyMaxContent for Rect<T> {
292     const MAX_CONTENT: Rect<T> =
293         Rect { left: T::MAX_CONTENT, right: T::MAX_CONTENT, top: T::MAX_CONTENT, bottom: T::MAX_CONTENT };
294 }
295 impl<T: TaffyMaxContent> Rect<T> {
296     /// Returns a Rect where the left, right, top, and bottom values are all the max_content value of the contained type
297     /// (e.g. Dimension::Auto or LengthPercentageAuto::Auto)
max_content() -> Self298     pub const fn max_content() -> Self {
299         max_content::<Self>()
300     }
301 }
302 
303 /// Returns a value of the inferred type which represent a `fit-content(…)` value
304 /// with the given argument.
fit_content<T: TaffyFitContent>(argument: LengthPercentage) -> T305 pub fn fit_content<T: TaffyFitContent>(argument: LengthPercentage) -> T {
306     T::fit_content(argument)
307 }
308 
309 /// Trait to create `fit-content(…)` values from plain numbers
310 pub trait TaffyFitContent {
311     /// Converts a LengthPercentage into Self
fit_content(argument: LengthPercentage) -> Self312     fn fit_content(argument: LengthPercentage) -> Self;
313 }
314 impl<T: TaffyFitContent> TaffyFitContent for Point<T> {
fit_content(argument: LengthPercentage) -> Self315     fn fit_content(argument: LengthPercentage) -> Self {
316         Point { x: T::fit_content(argument), y: T::fit_content(argument) }
317     }
318 }
319 impl<T: TaffyFitContent> Point<T> {
320     /// Returns a Point with x and y set to the same `fit-content(…)` value
321     /// with the given argument.
fit_content(argument: LengthPercentage) -> Self322     pub fn fit_content(argument: LengthPercentage) -> Self {
323         fit_content(argument)
324     }
325 }
326 impl<T: TaffyFitContent> TaffyFitContent for Line<T> {
fit_content(argument: LengthPercentage) -> Self327     fn fit_content(argument: LengthPercentage) -> Self {
328         Line { start: T::fit_content(argument), end: T::fit_content(argument) }
329     }
330 }
331 impl<T: TaffyFitContent> Line<T> {
332     /// Returns a Line with start and end set to the same `fit-content(…)` value
333     /// with the given argument.
fit_content(argument: LengthPercentage) -> Self334     pub fn fit_content(argument: LengthPercentage) -> Self {
335         fit_content(argument)
336     }
337 }
338 impl<T: TaffyFitContent> TaffyFitContent for Size<T> {
fit_content(argument: LengthPercentage) -> Self339     fn fit_content(argument: LengthPercentage) -> Self {
340         Size { width: T::fit_content(argument), height: T::fit_content(argument) }
341     }
342 }
343 impl<T: TaffyFitContent> Size<T> {
344     /// Returns a Size where with width and height set to the same `fit-content(…)` value
345     /// with the given argument.
fit_content(argument: LengthPercentage) -> Self346     pub fn fit_content(argument: LengthPercentage) -> Self {
347         fit_content(argument)
348     }
349 }
350 impl<T: TaffyFitContent> TaffyFitContent for Rect<T> {
fit_content(argument: LengthPercentage) -> Self351     fn fit_content(argument: LengthPercentage) -> Self {
352         Rect {
353             left: T::fit_content(argument),
354             right: T::fit_content(argument),
355             top: T::fit_content(argument),
356             bottom: T::fit_content(argument),
357         }
358     }
359 }
360 impl<T: TaffyFitContent> Rect<T> {
361     /// Returns a Rect where the left, right, top and bottom values are all constant fit_content value of the contained type
362     /// (e.g. 2.1, Some(2.1), or Dimension::Length(2.1))
fit_content(argument: LengthPercentage) -> Self363     pub fn fit_content(argument: LengthPercentage) -> Self {
364         fit_content(argument)
365     }
366 }
367 
368 /// Returns a value of the inferred type which represent an absolute length
length<Input: Into<f32> + Copy, T: FromLength>(value: Input) -> T369 pub fn length<Input: Into<f32> + Copy, T: FromLength>(value: Input) -> T {
370     T::from_length(value)
371 }
372 
373 /// Trait to create absolute length values from plain numbers
374 pub trait FromLength {
375     /// Converts into an `Into<f32>` into Self
from_length<Input: Into<f32> + Copy>(value: Input) -> Self376     fn from_length<Input: Into<f32> + Copy>(value: Input) -> Self;
377 }
378 impl FromLength for f32 {
from_length<Input: Into<f32> + Copy>(value: Input) -> Self379     fn from_length<Input: Into<f32> + Copy>(value: Input) -> Self {
380         value.into()
381     }
382 }
383 impl FromLength for Option<f32> {
from_length<Input: Into<f32> + Copy>(value: Input) -> Self384     fn from_length<Input: Into<f32> + Copy>(value: Input) -> Self {
385         Some(value.into())
386     }
387 }
388 impl<T: FromLength> FromLength for Point<T> {
from_length<Input: Into<f32> + Copy>(value: Input) -> Self389     fn from_length<Input: Into<f32> + Copy>(value: Input) -> Self {
390         Point { x: T::from_length(value.into()), y: T::from_length(value.into()) }
391     }
392 }
393 impl<T: FromLength> Point<T> {
394     /// Returns a Point where x and y values are the same given absolute length
length<Input: Into<f32> + Copy>(value: Input) -> Self395     pub fn length<Input: Into<f32> + Copy>(value: Input) -> Self {
396         length::<Input, Self>(value)
397     }
398 }
399 impl<T: FromLength> FromLength for Line<T> {
from_length<Input: Into<f32> + Copy>(value: Input) -> Self400     fn from_length<Input: Into<f32> + Copy>(value: Input) -> Self {
401         Line { start: T::from_length(value.into()), end: T::from_length(value.into()) }
402     }
403 }
404 impl<T: FromLength> Line<T> {
405     /// Returns a Line where both the start and end values are the same given absolute length
length<Input: Into<f32> + Copy>(value: Input) -> Self406     pub fn length<Input: Into<f32> + Copy>(value: Input) -> Self {
407         length::<Input, Self>(value)
408     }
409 }
410 impl<T: FromLength> FromLength for Size<T> {
from_length<Input: Into<f32> + Copy>(value: Input) -> Self411     fn from_length<Input: Into<f32> + Copy>(value: Input) -> Self {
412         Size { width: T::from_length(value.into()), height: T::from_length(value.into()) }
413     }
414 }
415 impl<T: FromLength> Size<T> {
416     /// Returns a Size where both the width and height values the same given absolute length
length<Input: Into<f32> + Copy>(value: Input) -> Self417     pub fn length<Input: Into<f32> + Copy>(value: Input) -> Self {
418         length::<Input, Self>(value)
419     }
420 }
421 impl<T: FromLength> FromLength for Rect<T> {
from_length<Input: Into<f32> + Copy>(value: Input) -> Self422     fn from_length<Input: Into<f32> + Copy>(value: Input) -> Self {
423         Rect {
424             left: T::from_length(value.into()),
425             right: T::from_length(value.into()),
426             top: T::from_length(value.into()),
427             bottom: T::from_length(value.into()),
428         }
429     }
430 }
431 impl<T: FromLength> Rect<T> {
432     /// Returns a Rect where the left, right, top and bottom values are all the same given absolute length
length<Input: Into<f32> + Copy>(value: Input) -> Self433     pub fn length<Input: Into<f32> + Copy>(value: Input) -> Self {
434         length::<Input, Self>(value)
435     }
436 }
437 
438 /// Returns a value of the inferred type which represent a percentage
percent<Input: Into<f32> + Copy, T: FromPercent>(percent: Input) -> T439 pub fn percent<Input: Into<f32> + Copy, T: FromPercent>(percent: Input) -> T {
440     T::from_percent(percent)
441 }
442 
443 /// Trait to create constant percent values from plain numbers
444 pub trait FromPercent {
445     /// Converts into an `Into<f32>` into Self
from_percent<Input: Into<f32> + Copy>(percent: Input) -> Self446     fn from_percent<Input: Into<f32> + Copy>(percent: Input) -> Self;
447 }
448 impl FromPercent for f32 {
from_percent<Input: Into<f32> + Copy>(percent: Input) -> Self449     fn from_percent<Input: Into<f32> + Copy>(percent: Input) -> Self {
450         percent.into()
451     }
452 }
453 impl FromPercent for Option<f32> {
from_percent<Input: Into<f32> + Copy>(percent: Input) -> Self454     fn from_percent<Input: Into<f32> + Copy>(percent: Input) -> Self {
455         Some(percent.into())
456     }
457 }
458 impl<T: FromPercent> FromPercent for Point<T> {
from_percent<Input: Into<f32> + Copy>(percent: Input) -> Self459     fn from_percent<Input: Into<f32> + Copy>(percent: Input) -> Self {
460         Point { x: T::from_percent(percent.into()), y: T::from_percent(percent.into()) }
461     }
462 }
463 impl<T: FromPercent> Point<T> {
464     /// Returns a Point where both the x and y values are the constant percent value of the contained type
465     /// (e.g. 2.1, Some(2.1), or Dimension::Length(2.1))
percent<Input: Into<f32> + Copy>(percent_value: Input) -> Self466     pub fn percent<Input: Into<f32> + Copy>(percent_value: Input) -> Self {
467         percent::<Input, Self>(percent_value)
468     }
469 }
470 impl<T: FromPercent> FromPercent for Line<T> {
from_percent<Input: Into<f32> + Copy>(percent: Input) -> Self471     fn from_percent<Input: Into<f32> + Copy>(percent: Input) -> Self {
472         Line { start: T::from_percent(percent.into()), end: T::from_percent(percent.into()) }
473     }
474 }
475 impl<T: FromPercent> Line<T> {
476     /// Returns a Line where both the start and end values are the constant percent value of the contained type
477     /// (e.g. 2.1, Some(2.1), or Dimension::Length(2.1))
percent<Input: Into<f32> + Copy>(percent_value: Input) -> Self478     pub fn percent<Input: Into<f32> + Copy>(percent_value: Input) -> Self {
479         percent::<Input, Self>(percent_value)
480     }
481 }
482 impl<T: FromPercent> FromPercent for Size<T> {
from_percent<Input: Into<f32> + Copy>(percent: Input) -> Self483     fn from_percent<Input: Into<f32> + Copy>(percent: Input) -> Self {
484         Size { width: T::from_percent(percent.into()), height: T::from_percent(percent.into()) }
485     }
486 }
487 impl<T: FromPercent> Size<T> {
488     /// Returns a Size where both the width and height values are the constant percent value of the contained type
489     /// (e.g. 2.1, Some(2.1), or Dimension::Length(2.1))
percent<Input: Into<f32> + Copy>(percent_value: Input) -> Self490     pub fn percent<Input: Into<f32> + Copy>(percent_value: Input) -> Self {
491         percent::<Input, Self>(percent_value)
492     }
493 }
494 impl<T: FromPercent> FromPercent for Rect<T> {
from_percent<Input: Into<f32> + Copy>(percent: Input) -> Self495     fn from_percent<Input: Into<f32> + Copy>(percent: Input) -> Self {
496         Rect {
497             left: T::from_percent(percent.into()),
498             right: T::from_percent(percent.into()),
499             top: T::from_percent(percent.into()),
500             bottom: T::from_percent(percent.into()),
501         }
502     }
503 }
504 impl<T: FromPercent> Rect<T> {
505     /// Returns a Rect where the left, right, top and bottom values are all constant percent value of the contained type
506     /// (e.g. 2.1, Some(2.1), or Dimension::Length(2.1))
percent<Input: Into<f32> + Copy>(percent_value: Input) -> Self507     pub fn percent<Input: Into<f32> + Copy>(percent_value: Input) -> Self {
508         percent::<Input, Self>(percent_value)
509     }
510 }
511 
512 /// Create a `Fraction` track sizing function (`fr` in CSS)
513 #[cfg(feature = "grid")]
fr<Input: Into<f32> + Copy, T: FromFlex>(flex: Input) -> T514 pub fn fr<Input: Into<f32> + Copy, T: FromFlex>(flex: Input) -> T {
515     T::from_flex(flex)
516 }
517 
518 /// Trait to create constant percent values from plain numbers
519 pub trait FromFlex {
520     /// Converts into an `Into<f32>` into Self
from_flex<Input: Into<f32> + Copy>(flex: Input) -> Self521     fn from_flex<Input: Into<f32> + Copy>(flex: Input) -> Self;
522 }
523 
524 #[cfg(feature = "grid")]
525 #[cfg(test)]
526 mod repeat_fn_tests {
527     use super::repeat;
528     use crate::style::{GridTrackRepetition, NonRepeatedTrackSizingFunction, TrackSizingFunction};
529 
530     const TEST_VEC: Vec<NonRepeatedTrackSizingFunction> = Vec::new();
531 
532     #[test]
test_repeat_u16()533     fn test_repeat_u16() {
534         assert_eq!(repeat(123, TEST_VEC), TrackSizingFunction::Repeat(GridTrackRepetition::Count(123), TEST_VEC));
535     }
536 
537     #[test]
test_repeat_auto_fit_str()538     fn test_repeat_auto_fit_str() {
539         assert_eq!(repeat("auto-fit", TEST_VEC), TrackSizingFunction::Repeat(GridTrackRepetition::AutoFit, TEST_VEC));
540     }
541 
542     #[test]
test_repeat_auto_fill_str()543     fn test_repeat_auto_fill_str() {
544         assert_eq!(repeat("auto-fill", TEST_VEC), TrackSizingFunction::Repeat(GridTrackRepetition::AutoFill, TEST_VEC));
545     }
546 }
547