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)]
16pub enum NoCalcNumeric {
17 Length(NoCalcLength),
21
22 Time(Time),
26
27 Number(Number),
31
32 Percentage(Percentage),
36 }
38
39impl NoCalcNumeric {
40 pub fn unitless_value(&self) -> CSSFloat {
42 match *self {
43 Self::Length(v) => v.unitless_value(),
44 Self::Time(v) => v.unitless_value(),
45 Self::Number(v) => v.get(),
46 Self::Percentage(v) => v.get(),
47 }
48 }
49
50 pub fn unit(&self) -> &'static str {
56 match *self {
57 Self::Length(v) => v.unit(),
58 Self::Time(v) => v.unit(),
59 Self::Number(v) => v.unit(),
60 Self::Percentage(v) => v.unit(),
61 }
62 }
63
64 pub fn canonical_unit(&self) -> Option<&'static str> {
69 match *self {
70 Self::Length(v) => v.canonical_unit(),
71 Self::Time(v) => v.canonical_unit(),
72 Self::Number(v) => v.canonical_unit(),
73 Self::Percentage(v) => v.canonical_unit(),
74 }
75 }
76
77 pub fn to(&self, unit: &str) -> Result<Self, ()> {
82 match self {
83 Self::Length(v) => Ok(Self::Length(v.to(unit)?)),
84 Self::Time(v) => Ok(Self::Time(v.to(unit)?)),
85 Self::Number(v) => Ok(Self::Number(v.to(unit)?)),
86 Self::Percentage(v) => Ok(Self::Percentage(v.to(unit)?)),
87 }
88 }
89
90 pub fn parse_unit_value(value: CSSFloat, unit: &str) -> Result<Self, ()> {
92 if let Ok(length) = NoCalcLength::parse_dimension_with_flags(
93 ParsingMode::DEFAULT,
94 false,
95 value,
96 unit,
97 ) {
98 return Ok(NoCalcNumeric::Length(length));
99 }
100
101 if let Ok(time) = Time::parse_dimension(value, unit) {
102 return Ok(NoCalcNumeric::Time(time));
103 }
104
105 match_ignore_ascii_case! { unit,
106 "number" => Ok(NoCalcNumeric::Number(Number::new(value))),
107 "percent" => Ok(NoCalcNumeric::Percentage(Percentage::new(value))),
108 _ => Err(()),
109 }
110
111 }
113}