From 35ed667f1670071187238a3aeacf56dca2d8ac00 Mon Sep 17 00:00:00 2001 From: ConnorSkees <39542938+ConnorSkees@users.noreply.github.com> Date: Sat, 15 Feb 2020 08:16:17 -0500 Subject: [PATCH] Implement builtin function `comparable()` --- src/builtin/math.rs | 12 +++++++++ src/units.rs | 65 ++++++++++++++++++++++++++++++++++++++++++++- tests/math.rs | 30 +++++++++++++++++++++ 3 files changed, 106 insertions(+), 1 deletion(-) diff --git a/src/builtin/math.rs b/src/builtin/math.rs index aa75042..4c4def4 100644 --- a/src/builtin/math.rs +++ b/src/builtin/math.rs @@ -36,4 +36,16 @@ pub(crate) fn register(f: &mut BTreeMap) { _ => todo!("expected number in builtin function `abs()`") } }); + decl!(f "comparable", |args, _| { + let unit1 = match arg!(args, 0, "number1").eval() { + Value::Dimension(_, u) => u, + _ => todo!("$number1: ___ is not a number.") + }; + let unit2 = match arg!(args, 1, "number2").eval() { + Value::Dimension(_, u) => u, + _ => todo!("$number2: ____ is not a number.") + }; + + Some(Value::bool(unit1.comparable(&unit2))) + }); } diff --git a/src/units.rs b/src/units.rs index c2606ee..72d34fd 100644 --- a/src/units.rs +++ b/src/units.rs @@ -25,7 +25,6 @@ pub(crate) enum Unit { Rem, /// Line height of the element Lh, - Percent, /// x-height of the element's font Ex, /// The advance measure (width) of the glyph "0" of the element's font @@ -86,6 +85,7 @@ pub(crate) enum Unit { // Other units /// Represents a fraction of the available space in the grid container Fr, + Percent, /// Unknown unit Unknown(String), @@ -93,6 +93,69 @@ pub(crate) enum Unit { None, } +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +pub(crate) enum UnitKind { + Absolute, + FontRelative, + ViewportRelative, + Angle, + Time, + Frequency, + Resolution, + Other, + None, +} + +impl Unit { + pub fn comparable(&self, other: &Unit) -> bool { + match self.kind() { + UnitKind::FontRelative | UnitKind::ViewportRelative | UnitKind::Other => self == other, + UnitKind::None => true, + u => other.kind() == u || other.kind() == UnitKind::None, + } + } + + pub fn kind(&self) -> UnitKind { + match self { + Unit::Px + | Unit::Mm + | Unit::In + | Unit::Cm + | Unit::Q + | Unit::Pt + | Unit::Pc => UnitKind::Absolute, + Unit::Em + | Unit::Rem + | Unit::Lh + | Unit::Ex + | Unit::Ch + | Unit::Cap + | Unit::Ic + | Unit::Rlh => UnitKind::FontRelative, + Unit::Vw + | Unit::Vh + | Unit::Vmin + | Unit::Vmax + | Unit::Vi + | Unit::Vb => UnitKind::ViewportRelative, + Unit::Deg + | Unit::Grad + | Unit::Rad + | Unit::Turn => UnitKind::Angle, + Unit::S + | Unit::Ms => UnitKind::Time, + Unit::Hz + | Unit::Khz => UnitKind::Frequency, + Unit::Dpi + | Unit::Dpcm + | Unit::Dppx + | Unit::X => UnitKind::Resolution, + Unit::None => UnitKind::None, + _ => UnitKind::Other, + } + } +} + impl From<&String> for Unit { fn from(unit: &String) -> Self { match unit.to_ascii_lowercase().as_bytes() { diff --git a/tests/math.rs b/tests/math.rs index a98d766..e35a89d 100644 --- a/tests/math.rs +++ b/tests/math.rs @@ -63,3 +63,33 @@ test!( "a {\n color: abs(-10px);\n}\n", "a {\n color: 10px;\n}\n" ); +test!( + comparable_unitless, + "a {\n color: comparable(1, 2);\n}\n", + "a {\n color: true;\n}\n" +); +test!( + comparable_none_px, + "a {\n color: comparable(1, 2px);\n}\n", + "a {\n color: true;\n}\n" +); +test!( + comparable_px_px, + "a {\n color: comparable(1px, 2px);\n}\n", + "a {\n color: true;\n}\n" +); +test!( + comparable_absolute, + "a {\n color: comparable(1px, 2in);\n}\n", + "a {\n color: true;\n}\n" +); +test!( + comparable_absolute_font_relative, + "a {\n color: comparable(1px, 2em);\n}\n", + "a {\n color: false;\n}\n" +); +test!( + comparable_named, + "a {\n color: comparable($number1: 1, $number2: 2);\n}\n", + "a {\n color: true;\n}\n" +);