Source code

Revision control

Copy as Markdown

Other Tools

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
//! Generic types for CSS values related to length.
use crate::parser::{Parse, ParserContext};
#[cfg(feature = "gecko")]
use crate::Zero;
use cssparser::Parser;
use style_traits::ParseError;
/// A `<length-percentage> | auto` value.
#[allow(missing_docs)]
#[derive(
Animate,
Clone,
ComputeSquaredDistance,
Copy,
Debug,
MallocSizeOf,
PartialEq,
SpecifiedValueInfo,
ToAnimatedValue,
ToAnimatedZero,
ToComputedValue,
ToCss,
ToResolvedValue,
ToShmem,
)]
#[repr(C, u8)]
pub enum GenericLengthPercentageOrAuto<LengthPercent> {
LengthPercentage(LengthPercent),
Auto,
}
pub use self::GenericLengthPercentageOrAuto as LengthPercentageOrAuto;
impl<LengthPercentage> LengthPercentageOrAuto<LengthPercentage> {
/// `auto` value.
#[inline]
pub fn auto() -> Self {
LengthPercentageOrAuto::Auto
}
/// Whether this is the `auto` value.
#[inline]
pub fn is_auto(&self) -> bool {
matches!(*self, LengthPercentageOrAuto::Auto)
}
/// A helper function to parse this with quirks or not and so forth.
pub fn parse_with<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
parser: impl FnOnce(
&ParserContext,
&mut Parser<'i, 't>,
) -> Result<LengthPercentage, ParseError<'i>>,
) -> Result<Self, ParseError<'i>> {
if input.try_parse(|i| i.expect_ident_matching("auto")).is_ok() {
return Ok(LengthPercentageOrAuto::Auto);
}
Ok(LengthPercentageOrAuto::LengthPercentage(parser(
context, input,
)?))
}
}
impl<LengthPercentage> LengthPercentageOrAuto<LengthPercentage>
where
LengthPercentage: Clone,
{
/// Resolves `auto` values by calling `f`.
#[inline]
pub fn auto_is(&self, f: impl FnOnce() -> LengthPercentage) -> LengthPercentage {
match self {
LengthPercentageOrAuto::LengthPercentage(length) => length.clone(),
LengthPercentageOrAuto::Auto => f(),
}
}
/// Returns the non-`auto` value, if any.
#[inline]
pub fn non_auto(&self) -> Option<LengthPercentage> {
match self {
LengthPercentageOrAuto::LengthPercentage(length) => Some(length.clone()),
LengthPercentageOrAuto::Auto => None,
}
}
/// Maps the length of this value.
pub fn map<T>(&self, f: impl FnOnce(LengthPercentage) -> T) -> LengthPercentageOrAuto<T> {
match self {
LengthPercentageOrAuto::LengthPercentage(l) => {
LengthPercentageOrAuto::LengthPercentage(f(l.clone()))
},
LengthPercentageOrAuto::Auto => LengthPercentageOrAuto::Auto,
}
}
}
impl<LengthPercentage: Zero> Zero for LengthPercentageOrAuto<LengthPercentage> {
fn zero() -> Self {
LengthPercentageOrAuto::LengthPercentage(Zero::zero())
}
fn is_zero(&self) -> bool {
match *self {
LengthPercentageOrAuto::LengthPercentage(ref l) => l.is_zero(),
LengthPercentageOrAuto::Auto => false,
}
}
}
impl<LengthPercentage: Parse> Parse for LengthPercentageOrAuto<LengthPercentage> {
fn parse<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> {
Self::parse_with(context, input, LengthPercentage::parse)
}
}
/// A generic value for the `width`, `height`, `min-width`, or `min-height` property.
///
/// Unlike `max-width` or `max-height` properties, a Size can be `auto`,
/// and cannot be `none`.
///
/// Note that it only accepts non-negative values.
#[allow(missing_docs)]
#[derive(
Animate,
Clone,
ComputeSquaredDistance,
Copy,
Debug,
MallocSizeOf,
PartialEq,
SpecifiedValueInfo,
ToAnimatedValue,
ToAnimatedZero,
ToComputedValue,
ToCss,
ToResolvedValue,
ToShmem,
)]
#[repr(C, u8)]
pub enum GenericSize<LengthPercent> {
LengthPercentage(LengthPercent),
Auto,
#[animation(error)]
MaxContent,
#[animation(error)]
MinContent,
#[animation(error)]
FitContent,
#[animation(error)]
MozAvailable,
#[animation(error)]
#[css(function = "fit-content")]
FitContentFunction(LengthPercent),
}
pub use self::GenericSize as Size;
impl<LengthPercentage> Size<LengthPercentage> {
/// `auto` value.
#[inline]
pub fn auto() -> Self {
Size::Auto
}
/// Returns whether we're the auto value.
#[inline]
pub fn is_auto(&self) -> bool {
matches!(*self, Size::Auto)
}
}
/// A generic value for the `max-width` or `max-height` property.
#[allow(missing_docs)]
#[derive(
Animate,
Clone,
ComputeSquaredDistance,
Copy,
Debug,
MallocSizeOf,
PartialEq,
SpecifiedValueInfo,
ToAnimatedValue,
ToAnimatedZero,
ToComputedValue,
ToCss,
ToResolvedValue,
ToShmem,
)]
#[repr(C, u8)]
pub enum GenericMaxSize<LengthPercent> {
LengthPercentage(LengthPercent),
None,
#[animation(error)]
MaxContent,
#[animation(error)]
MinContent,
#[animation(error)]
FitContent,
#[animation(error)]
MozAvailable,
#[animation(error)]
#[css(function = "fit-content")]
FitContentFunction(LengthPercent),
}
pub use self::GenericMaxSize as MaxSize;
impl<LengthPercentage> MaxSize<LengthPercentage> {
/// `none` value.
#[inline]
pub fn none() -> Self {
MaxSize::None
}
}
/// A generic `<length>` | `<number>` value for the `tab-size` property.
#[derive(
Animate,
Clone,
ComputeSquaredDistance,
Copy,
Debug,
MallocSizeOf,
Parse,
PartialEq,
SpecifiedValueInfo,
ToAnimatedValue,
ToAnimatedZero,
ToComputedValue,
ToCss,
ToResolvedValue,
ToShmem,
)]
#[repr(C, u8)]
pub enum GenericLengthOrNumber<L, N> {
/// A number.
///
/// NOTE: Numbers need to be before lengths, in order to parse them
/// first, since `0` should be a number, not the `0px` length.
Number(N),
/// A length.
Length(L),
}
pub use self::GenericLengthOrNumber as LengthOrNumber;
impl<L, N: Zero> Zero for LengthOrNumber<L, N> {
fn zero() -> Self {
LengthOrNumber::Number(Zero::zero())
}
fn is_zero(&self) -> bool {
match *self {
LengthOrNumber::Number(ref n) => n.is_zero(),
LengthOrNumber::Length(..) => false,
}
}
}
/// A generic `<length-percentage>` | normal` value.
#[derive(
Animate,
Clone,
ComputeSquaredDistance,
Copy,
Debug,
MallocSizeOf,
Parse,
PartialEq,
SpecifiedValueInfo,
ToAnimatedValue,
ToAnimatedZero,
ToComputedValue,
ToCss,
ToResolvedValue,
ToShmem,
)]
#[repr(C, u8)]
#[allow(missing_docs)]
pub enum GenericLengthPercentageOrNormal<LengthPercent> {
LengthPercentage(LengthPercent),
Normal,
}
pub use self::GenericLengthPercentageOrNormal as LengthPercentageOrNormal;
impl<LengthPercent> LengthPercentageOrNormal<LengthPercent> {
/// Returns the normal value.
#[inline]
pub fn normal() -> Self {
LengthPercentageOrNormal::Normal
}
}