/* 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 ` | 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 { LengthPercentage(LengthPercent), Auto, } pub use self::GenericLengthPercentageOrAuto as LengthPercentageOrAuto; impl LengthPercentageOrAuto { /// `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>, ) -> Result> { if input.try_parse(|i| i.expect_ident_matching("auto")).is_ok() { return Ok(LengthPercentageOrAuto::Auto); } Ok(LengthPercentageOrAuto::LengthPercentage(parser( context, input, )?)) } } impl LengthPercentageOrAuto 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 { match self { LengthPercentageOrAuto::LengthPercentage(length) => Some(length.clone()), LengthPercentageOrAuto::Auto => None, } } /// Maps the length of this value. pub fn map(&self, f: impl FnOnce(LengthPercentage) -> T) -> LengthPercentageOrAuto { match self { LengthPercentageOrAuto::LengthPercentage(l) => { LengthPercentageOrAuto::LengthPercentage(f(l.clone())) }, LengthPercentageOrAuto::Auto => LengthPercentageOrAuto::Auto, } } } impl Zero for LengthPercentageOrAuto { 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 Parse for LengthPercentageOrAuto { fn parse<'i, 't>( context: &ParserContext, input: &mut Parser<'i, 't>, ) -> Result> { 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 { 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 Size { /// `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 { 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 MaxSize { /// `none` value. #[inline] pub fn none() -> Self { MaxSize::None } } /// A generic `` | `` 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 { /// 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 Zero for LengthOrNumber { 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 `` | 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 { LengthPercentage(LengthPercent), Normal, } pub use self::GenericLengthPercentageOrNormal as LengthPercentageOrNormal; impl LengthPercentageOrNormal { /// Returns the normal value. #[inline] pub fn normal() -> Self { LengthPercentageOrNormal::Normal } }