Skip to main content

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}