Implement builtin function comparable()

This commit is contained in:
ConnorSkees 2020-02-15 08:16:17 -05:00
parent 3823a0f9cd
commit 35ed667f16
3 changed files with 106 additions and 1 deletions

View File

@ -36,4 +36,16 @@ pub(crate) fn register(f: &mut BTreeMap<String, Builtin>) {
_ => todo!("expected number in builtin function `abs()`") _ => 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)))
});
} }

View File

@ -25,7 +25,6 @@ pub(crate) enum Unit {
Rem, Rem,
/// Line height of the element /// Line height of the element
Lh, Lh,
Percent,
/// x-height of the element's font /// x-height of the element's font
Ex, Ex,
/// The advance measure (width) of the glyph "0" of the element's font /// The advance measure (width) of the glyph "0" of the element's font
@ -86,6 +85,7 @@ pub(crate) enum Unit {
// Other units // Other units
/// Represents a fraction of the available space in the grid container /// Represents a fraction of the available space in the grid container
Fr, Fr,
Percent,
/// Unknown unit /// Unknown unit
Unknown(String), Unknown(String),
@ -93,6 +93,69 @@ pub(crate) enum Unit {
None, 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 { impl From<&String> for Unit {
fn from(unit: &String) -> Self { fn from(unit: &String) -> Self {
match unit.to_ascii_lowercase().as_bytes() { match unit.to_ascii_lowercase().as_bytes() {

View File

@ -63,3 +63,33 @@ test!(
"a {\n color: abs(-10px);\n}\n", "a {\n color: abs(-10px);\n}\n",
"a {\n color: 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"
);