style/typed_om/numeric_values.rs
1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5//! Typed OM Numeric Values.
6
7use crate::derives::*;
8use crate::values::specified::{NoCalcLength, Number, Percentage};
9use crate::values::CSSFloat;
10use cssparser::match_ignore_ascii_case;
11use style_traits::ParsingMode;
12
13/// A numeric value without a `calc` expression.
14#[derive(Clone, ToTyped)]
15#[repr(u8)]
16#[typed_value(derive_fields)]
17pub enum NoCalcNumeric {
18 /// A `<length>` value.
19 ///
20 /// <https://drafts.csswg.org/css-values/#lengths>
21 Length(NoCalcLength),
22
23 /// A `<number>` value.
24 ///
25 /// <https://drafts.csswg.org/css-values/#number-value>
26 Number(Number),
27
28 /// A `<percentage>` value.
29 ///
30 /// <https://drafts.csswg.org/css-values/#percentages>
31 Percentage(Percentage),
32 // TODO: Add other values.
33}
34
35impl NoCalcNumeric {
36 /// Return the unitless, raw value.
37 pub fn unitless_value(&self) -> CSSFloat {
38 match *self {
39 Self::Length(v) => v.unitless_value(),
40 Self::Number(v) => v.get(),
41 Self::Percentage(v) => v.get(),
42 }
43 }
44
45 /// Return the unit, as a string.
46 ///
47 /// TODO: Investigate returning SortKey or adding a new variant for
48 /// returning the unit as SortKey. Tracked in
49 /// <https://bugzilla.mozilla.org/show_bug.cgi?id=2015863>
50 pub fn unit(&self) -> &'static str {
51 match *self {
52 Self::Length(v) => v.unit(),
53 Self::Number(v) => v.unit(),
54 Self::Percentage(v) => v.unit(),
55 }
56 }
57
58 /// Return the canonical unit for this value, if one exists.
59 ///
60 /// TODO: Investigate returning SortKey. Tracked in
61 /// <https://bugzilla.mozilla.org/show_bug.cgi?id=2015863>
62 pub fn canonical_unit(&self) -> Option<&'static str> {
63 match *self {
64 Self::Length(v) => v.canonical_unit(),
65 Self::Number(v) => v.canonical_unit(),
66 Self::Percentage(v) => v.canonical_unit(),
67 }
68 }
69
70 /// Convert this value to the specified unit, if possible.
71 ///
72 /// TODO: Investigate using SortKey. Tracked in
73 /// <https://bugzilla.mozilla.org/show_bug.cgi?id=2015863>
74 pub fn to(&self, unit: &str) -> Result<Self, ()> {
75 match self {
76 Self::Length(v) => Ok(Self::Length(v.to(unit)?)),
77 Self::Number(v) => Ok(Self::Number(v.to(unit)?)),
78 Self::Percentage(v) => Ok(Self::Percentage(v.to(unit)?)),
79 }
80 }
81
82 /// Parse a given unit value.
83 pub fn parse_unit_value(value: CSSFloat, unit: &str) -> Result<Self, ()> {
84 if let Ok(length) = NoCalcLength::parse_dimension_with_flags(
85 ParsingMode::DEFAULT,
86 /* in_page_rule = */ false,
87 value,
88 unit,
89 ) {
90 return Ok(NoCalcNumeric::Length(length));
91 }
92
93 match_ignore_ascii_case! { unit,
94 "number" => Ok(NoCalcNumeric::Number(Number::new(value))),
95 "percent" => Ok(NoCalcNumeric::Percentage(Percentage::new(value))),
96 _ => Err(()),
97 }
98
99 // TODO: Add support for other values.
100 }
101}