//! Helper functions which it make it easier to create instances of types in the `style` and `geometry` modules.
use crate::{
geometry::{Line, Point, Rect, Size},
style::LengthPercentage,
};
#[cfg(feature = "grid")]
use crate::{
geometry::MinMax,
style::{
GridTrackRepetition, MaxTrackSizingFunction, MinTrackSizingFunction, NonRepeatedTrackSizingFunction,
TrackSizingFunction,
},
sys::Vec,
};
#[cfg(feature = "grid")]
use core::fmt::Debug;
/// Returns an auto-repeated track definition
#[cfg(feature = "grid")]
pub fn repeat (repetition_kind: Input, track_list: Vec) -> TrackSizingFunction
where
Input: TryInto,
>::Error: Debug,
{
TrackSizingFunction::Repeat(repetition_kind.try_into().unwrap(), track_list)
}
#[cfg(feature = "grid")]
#[cfg(test)]
mod repeat_fn_tests {
use super::repeat;
use crate::style::{GridTrackRepetition, NonRepeatedTrackSizingFunction, TrackSizingFunction};
const TEST_VEC: Vec = Vec::new();
#[test]
fn test_repeat_u16() {
assert_eq!(repeat(123, TEST_VEC), TrackSizingFunction::Repeat(GridTrackRepetition::Count(123), TEST_VEC));
}
#[test]
fn test_repeat_auto_fit_str() {
assert_eq!(repeat("auto-fit", TEST_VEC), TrackSizingFunction::Repeat(GridTrackRepetition::AutoFit, TEST_VEC));
}
#[test]
fn test_repeat_auto_fill_str() {
assert_eq!(repeat("auto-fill", TEST_VEC), TrackSizingFunction::Repeat(GridTrackRepetition::AutoFill, TEST_VEC));
}
}
#[cfg(feature = "grid")]
/// Returns a grid template containing `count` evenly sized tracks
pub fn evenly_sized_tracks(count: u16) -> Vec {
use crate::sys::new_vec_with_capacity;
let mut repeated_tracks = new_vec_with_capacity(1);
repeated_tracks.push(flex(1.0f32));
let mut tracks = new_vec_with_capacity(1);
tracks.push(repeat(count, repeated_tracks));
tracks
}
/// Specifies a grid line to place a grid item between in CSS Grid Line coordinates:
/// - Positive indicies count upwards from the start (top or left) of the explicit grid
/// - Negative indicies count downwards from the end (bottom or right) of the explicit grid
/// - ZERO IS INVALID index, and will be treated as a GridPlacement::Auto.
pub fn line(index: i16) -> T {
T::from_line_index(index)
}
/// Trait to abstract over grid line values
pub trait TaffyGridLine {
/// Converts an i16 into Self
fn from_line_index(index: i16) -> Self;
}
/// Returns a GridPlacement::Span
pub fn span(span: u16) -> T {
T::from_span(span)
}
/// Trait to abstract over grid span values
pub trait TaffyGridSpan {
/// Converts an iu6 into Self
fn from_span(span: u16) -> Self;
}
/// Returns a MinMax with min value of min and max value of max
#[cfg(feature = "grid")]
pub fn minmax(min: MinTrackSizingFunction, max: MaxTrackSizingFunction) -> Output
where
Output: From>,
{
MinMax { min, max }.into()
}
/// Shorthand for minmax(0, Nfr). Probably what you want if you want exactly evenly sized tracks.
#[cfg(feature = "grid")]
pub fn flex (flex_fraction: Input) -> Output
where
Input: Into + Copy,
Output: From>,
{
MinMax { min: zero(), max: fr(flex_fraction.into()) }.into()
}
/// 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 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 Line {
const ZERO: Line = Line { start: T::ZERO, end: T::ZERO };
}
impl Line {
/// Returns a Line where both the start and end 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 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 Line {
const AUTO: Line = Line { start: T::AUTO, end: T::AUTO };
}
impl Line {
/// Returns a Line where both the start and end 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 the auto value for that type
pub const fn min_content() -> T {
T::MIN_CONTENT
}
/// Trait to abstract over min_content values
pub trait TaffyMinContent {
/// The min_content value for type implementing TaffyZero
const MIN_CONTENT: Self;
}
impl TaffyMinContent for Option {
const MIN_CONTENT: Option = Some(T::MIN_CONTENT);
}
impl TaffyMinContent for Point {
const MIN_CONTENT: Point = Point { x: T::MIN_CONTENT, y: T::MIN_CONTENT };
}
impl Point {
/// Returns a Point where both the x and y values are the min_content value of the contained type
/// (e.g. Dimension::Auto or LengthPercentageAuto::Auto)
pub const fn min_content() -> Self {
min_content::()
}
}
impl TaffyMinContent for Line {
const MIN_CONTENT: Line = Line { start: T::MIN_CONTENT, end: T::MIN_CONTENT };
}
impl Line {
/// Returns a Line where both the start and end values are the min_content value of the contained type
/// (e.g. Dimension::Auto or LengthPercentageAuto::Auto)
pub const fn min_content() -> Self {
min_content::()
}
}
impl TaffyMinContent for Size {
const MIN_CONTENT: Size = Size { width: T::MIN_CONTENT, height: T::MIN_CONTENT };
}
impl Size {
/// Returns a Size where both the width and height values are the min_content value of the contained type
/// (e.g. Dimension::Auto or LengthPercentageAuto::Auto)
pub const fn min_content() -> Self {
min_content::()
}
}
impl TaffyMinContent for Rect {
const MIN_CONTENT: Rect =
Rect { left: T::MIN_CONTENT, right: T::MIN_CONTENT, top: T::MIN_CONTENT, bottom: T::MIN_CONTENT };
}
impl Rect {
/// Returns a Size where the left, right, top, and bottom values are all the min_content value of the contained type
/// (e.g. Dimension::Auto or LengthPercentageAuto::Auto)
pub const fn min_content() -> Self {
min_content::()
}
}
/// Returns the auto value for that type
pub const fn max_content() -> T {
T::MAX_CONTENT
}
/// Trait to abstract over max_content values
pub trait TaffyMaxContent {
/// The max_content value for type implementing TaffyZero
const MAX_CONTENT: Self;
}
impl TaffyMaxContent for Option {
const MAX_CONTENT: Option = Some(T::MAX_CONTENT);
}
impl TaffyMaxContent for Point {
const MAX_CONTENT: Point = Point { x: T::MAX_CONTENT, y: T::MAX_CONTENT };
}
impl Point {
/// Returns a Point where both the x and y values are the max_content value of the contained type
/// (e.g. Dimension::Auto or LengthPercentageAuto::Auto)
pub const fn max_content() -> Self {
max_content::()
}
}
impl TaffyMaxContent for Line {
const MAX_CONTENT: Line = Line { start: T::MAX_CONTENT, end: T::MAX_CONTENT };
}
impl Line {
/// Returns a Line where both the start and end values are the max_content value of the contained type
/// (e.g. Dimension::Auto or LengthPercentageAuto::Auto)
pub const fn max_content() -> Self {
max_content::()
}
}
impl TaffyMaxContent for Size {
const MAX_CONTENT: Size = Size { width: T::MAX_CONTENT, height: T::MAX_CONTENT };
}
impl Size {
/// Returns a Size where both the width and height values are the max_content value of the contained type
/// (e.g. Dimension::Auto or LengthPercentageAuto::Auto)
pub const fn max_content() -> Self {
max_content::()
}
}
impl TaffyMaxContent for Rect {
const MAX_CONTENT: Rect =
Rect { left: T::MAX_CONTENT, right: T::MAX_CONTENT, top: T::MAX_CONTENT, bottom: T::MAX_CONTENT };
}
impl Rect {
/// Returns a Size where the left, right, top, and bottom values are all the max_content value of the contained type
/// (e.g. Dimension::Auto or LengthPercentageAuto::Auto)
pub const fn max_content() -> Self {
max_content::()
}
}
/// Returns a value of the inferred type which represent a constant of points
pub fn fit_content(argument: LengthPercentage) -> T {
T::fit_content(argument)
}
/// Trait to create constant points values from plain numbers
pub trait TaffyFitContent {
/// Converts into a LengthPercentage into Self
fn fit_content(argument: LengthPercentage) -> Self;
}
impl TaffyFitContent for Point {
fn fit_content(argument: LengthPercentage) -> Self {
Point { x: T::fit_content(argument), y: T::fit_content(argument) }
}
}
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 fit_content(argument: LengthPercentage) -> Self {
fit_content(argument)
}
}
impl TaffyFitContent for Line {
fn fit_content(argument: LengthPercentage) -> Self {
Line { start: T::fit_content(argument), end: T::fit_content(argument) }
}
}
impl Line {
/// Returns a Line where both the start and end values are the constant points value of the contained type
/// (e.g. 2.1, Some(2.1), or Dimension::Points(2.1))
pub fn fit_content(argument: LengthPercentage) -> Self {
fit_content(argument)
}
}
impl TaffyFitContent for Size {
fn fit_content(argument: LengthPercentage) -> Self {
Size { width: T::fit_content(argument), height: T::fit_content(argument) }
}
}
impl Size {
/// Returns a Size where both the width and height values are the constant fit_content value of the contained type
/// (e.g. 2.1, Some(2.1), or Dimension::Points(2.1))
pub fn fit_content(argument: LengthPercentage) -> Self {
fit_content(argument)
}
}
impl TaffyFitContent for Rect {
fn fit_content(argument: LengthPercentage) -> Self {
Rect {
left: T::fit_content(argument),
right: T::fit_content(argument),
top: T::fit_content(argument),
bottom: T::fit_content(argument),
}
}
}
impl Rect {
/// Returns a Rect where the left, right, top and bottom values are all constant fit_content value of the contained type
/// (e.g. 2.1, Some(2.1), or Dimension::Points(2.1))
pub fn fit_content(argument: LengthPercentage) -> Self {
fit_content(argument)
}
}
/// 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 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 Line {
fn from_points + Copy>(points: Input) -> Self {
Line { start: T::from_points(points.into()), end: T::from_points(points.into()) }
}
}
impl Line {
/// Returns a Line where both the start and end 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)
}
}
/// Returns a value of the inferred type which represent a constant of points
pub fn percent + Copy, T: FromPercent>(percent: Input) -> T {
T::from_percent(percent)
}
/// Trait to create constant percent values from plain numbers
pub trait FromPercent {
/// Converts into an `Into` into Self
fn from_percent + Copy>(percent: Input) -> Self;
}
impl FromPercent for f32 {
fn from_percent + Copy>(percent: Input) -> Self {
percent.into()
}
}
impl FromPercent for Option {
fn from_percent + Copy>(percent: Input) -> Self {
Some(percent.into())
}
}
impl FromPercent for Point {
fn from_percent + Copy>(percent: Input) -> Self {
Point { x: T::from_percent(percent.into()), y: T::from_percent(percent.into()) }
}
}
impl Point {
/// Returns a Point where both the x and y values are the constant percent value of the contained type
/// (e.g. 2.1, Some(2.1), or Dimension::Points(2.1))
pub fn percent + Copy>(percent_value: Input) -> Self {
percent:: (percent_value)
}
}
impl FromPercent for Line {
fn from_percent + Copy>(percent: Input) -> Self {
Line { start: T::from_percent(percent.into()), end: T::from_percent(percent.into()) }
}
}
impl Line {
/// Returns a Line where both the start and end values are the constant percent value of the contained type
/// (e.g. 2.1, Some(2.1), or Dimension::Points(2.1))
pub fn percent + Copy>(percent_value: Input) -> Self {
percent:: (percent_value)
}
}
impl FromPercent for Size {
fn from_percent + Copy>(percent: Input) -> Self {
Size { width: T::from_percent(percent.into()), height: T::from_percent(percent.into()) }
}
}
impl Size {
/// Returns a Size where both the width and height values are the constant percent value of the contained type
/// (e.g. 2.1, Some(2.1), or Dimension::Points(2.1))
pub fn percent + Copy>(percent_value: Input) -> Self {
percent:: (percent_value)
}
}
impl FromPercent for Rect {
fn from_percent + Copy>(percent: Input) -> Self {
Rect {
left: T::from_percent(percent.into()),
right: T::from_percent(percent.into()),
top: T::from_percent(percent.into()),
bottom: T::from_percent(percent.into()),
}
}
}
impl Rect {
/// Returns a Rect where the left, right, top and bottom values are all constant percent value of the contained type
/// (e.g. 2.1, Some(2.1), or Dimension::Points(2.1))
pub fn percent + Copy>(percent_value: Input) -> Self {
percent:: (percent_value)
}
}
/// Create a `Fraction` track sizing function (`fr` in CSS)
#[cfg(feature = "grid")]
pub fn fr + Copy, T: FromFlex>(flex: Input) -> T {
T::from_flex(flex)
}
/// Trait to create constant percent values from plain numbers
pub trait FromFlex {
/// Converts into an `Into` into Self
fn from_flex + Copy>(flex: Input) -> Self;
}