style/typed_om/
numeric_declaration.rs1use crate::derives::*;
8use crate::parser::{Parse, ParserContext};
9use crate::typed_om::numeric::NoCalcNumeric;
10use crate::values::generics::calc::CalcUnits;
11use crate::values::specified::calc::{CalcNode, CalcParseFlags};
12use crate::values::specified::{
13 NoCalcAngle, NoCalcLength, NoCalcNumber, NoCalcPercentage, NoCalcTime,
14};
15use cssparser::{Parser, Token};
16use style_traits::values::specified::AllowedNumericType;
17use style_traits::{ParseError, StyleParseErrorKind};
18
19#[derive(Clone, ToTyped)]
21pub enum NumericDeclaration {
22 NoCalc(NoCalcNumeric),
24
25 Calc(CalcNode),
29}
30
31impl Parse for NumericDeclaration {
32 fn parse<'i, 't>(
34 context: &ParserContext,
35 input: &mut Parser<'i, 't>,
36 ) -> Result<Self, ParseError<'i>> {
37 let location = input.current_source_location();
38
39 let token = input.next()?;
41
42 match *token {
44 Token::Number { value, .. } => Ok(Self::NoCalc(NoCalcNumeric::Number(
45 NoCalcNumber::new(value),
46 ))),
47
48 Token::Percentage { unit_value, .. } => Ok(Self::NoCalc(NoCalcNumeric::Percentage(
49 NoCalcPercentage::new(unit_value),
50 ))),
51
52 Token::Dimension {
53 value, ref unit, ..
54 } => {
55 if let Ok(length) = NoCalcLength::parse_dimension_with_context(context, value, unit)
56 {
57 return Ok(Self::NoCalc(NoCalcNumeric::Length(length)));
58 }
59
60 if let Ok(angle) = NoCalcAngle::parse_dimension(value, unit) {
61 return Ok(Self::NoCalc(NoCalcNumeric::Angle(angle)));
62 }
63
64 if let Ok(time) = NoCalcTime::parse_dimension(value, unit) {
65 return Ok(Self::NoCalc(NoCalcNumeric::Time(time)));
66 }
67
68 Err(location.new_unexpected_token_error(token.clone()))
69
70 },
75
76 Token::Function(ref name) => {
77 let function = CalcNode::math_function(context, name, location)?;
78 let allow_all_units = CalcParseFlags::new(CalcUnits::ALL);
79 let node = CalcNode::parse(context, input, function, allow_all_units)?;
80
81 let allow_all_types = AllowedNumericType::All;
82 let _ = node
83 .clone()
84 .into_length_or_percentage(allow_all_types)
85 .map_err(|()| {
86 location.new_custom_error(StyleParseErrorKind::UnspecifiedError)
87 })?;
88
89 Ok(Self::Calc(node))
92 },
93
94 ref token => return Err(location.new_unexpected_token_error(token.clone())),
95 }
96 }
97}