style/typed_om/
numeric_values.rs1use crate::derives::*;
8use crate::values::specified::{NoCalcLength, Number, Percentage, Time};
9use crate::values::CSSFloat;
10use cssparser::match_ignore_ascii_case;
11use style_traits::ParsingMode;
12
13#[derive(Clone, ToTyped)]
15#[repr(u8)]
16#[typed_value(derive_fields)]
17pub enum NoCalcNumeric {
18 Length(NoCalcLength),
22
23 Time(Time),
27
28 Number(Number),
32
33 Percentage(Percentage),
37 }
39
40impl NoCalcNumeric {
41 pub fn unitless_value(&self) -> CSSFloat {
43 match *self {
44 Self::Length(v) => v.unitless_value(),
45 Self::Time(v) => v.unitless_value(),
46 Self::Number(v) => v.get(),
47 Self::Percentage(v) => v.get(),
48 }
49 }
50
51 pub fn unit(&self) -> &'static str {
57 match *self {
58 Self::Length(v) => v.unit(),
59 Self::Time(v) => v.unit(),
60 Self::Number(v) => v.unit(),
61 Self::Percentage(v) => v.unit(),
62 }
63 }
64
65 pub fn canonical_unit(&self) -> Option<&'static str> {
70 match *self {
71 Self::Length(v) => v.canonical_unit(),
72 Self::Time(v) => v.canonical_unit(),
73 Self::Number(v) => v.canonical_unit(),
74 Self::Percentage(v) => v.canonical_unit(),
75 }
76 }
77
78 pub fn to(&self, unit: &str) -> Result<Self, ()> {
83 match self {
84 Self::Length(v) => Ok(Self::Length(v.to(unit)?)),
85 Self::Time(v) => Ok(Self::Time(v.to(unit)?)),
86 Self::Number(v) => Ok(Self::Number(v.to(unit)?)),
87 Self::Percentage(v) => Ok(Self::Percentage(v.to(unit)?)),
88 }
89 }
90
91 pub fn parse_unit_value(value: CSSFloat, unit: &str) -> Result<Self, ()> {
93 if let Ok(length) = NoCalcLength::parse_dimension_with_flags(
94 ParsingMode::DEFAULT,
95 false,
96 value,
97 unit,
98 ) {
99 return Ok(NoCalcNumeric::Length(length));
100 }
101
102 if let Ok(time) = Time::parse_dimension(value, unit) {
103 return Ok(NoCalcNumeric::Time(time));
104 }
105
106 match_ignore_ascii_case! { unit,
107 "number" => Ok(NoCalcNumeric::Number(Number::new(value))),
108 "percent" => Ok(NoCalcNumeric::Percentage(Percentage::new(value))),
109 _ => Err(()),
110 }
111
112 }
114}