From 3b5dd73a655c617dd973f0f448a0cd9ffb9ad80c Mon Sep 17 00:00:00 2001 From: ConnorSkees <39542938+ConnorSkees@users.noreply.github.com> Date: Tue, 17 Mar 2020 10:06:24 -0400 Subject: [PATCH] Support arbitrary amount of numbers multiplied together --- src/units.rs | 23 +++++++++++++++++++---- src/value/ops.rs | 13 ++++++++++++- tests/units.rs | 10 ++++++++++ 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/src/units.rs b/src/units.rs index 4a8738e..6dd29b8 100644 --- a/src/units.rs +++ b/src/units.rs @@ -92,8 +92,8 @@ pub(crate) enum Unit { /// Unspecified unit None, - /// Two units multiplied together - Mul(Box, Box), + /// Units multiplied together + Mul(Vec), /// A unit divided by another Div(Box, Box), } @@ -228,7 +228,15 @@ impl Into for Unit { Unit::X => "x", Unit::Fr => "fr", Unit::None => "", - Unit::Mul(l, r) => return format!("{}*{}", l, r), + Unit::Mul(u) => { + return format!( + "{}", + u.into_iter() + .map(|x| x.to_string()) + .collect::>() + .join("*") + ) + } Unit::Div(l, r) => return format!("{}/{}", l, r), Unit::Unknown(ref s) => s, } @@ -276,7 +284,14 @@ impl fmt::Display for Unit { Unit::Fr => write!(f, "fr"), Unit::Unknown(s) => write!(f, "{}", s), Unit::None => write!(f, ""), - Unit::Mul(l, r) => write!(f, "{}*{}", l, r), + Unit::Mul(u) => write!( + f, + "{}", + u.into_iter() + .map(|x| x.to_string()) + .collect::>() + .join("*") + ), Unit::Div(l, r) => write!(f, "{}/{}", l, r), } } diff --git a/src/value/ops.rs b/src/value/ops.rs index a7f4f5f..a82cdeb 100644 --- a/src/value/ops.rs +++ b/src/value/ops.rs @@ -204,10 +204,20 @@ impl Mul for Value { Value::Dimension(num * num2, unit2) } else if unit2 == Unit::None { Value::Dimension(num * num2, unit) + } else if let Unit::Mul(mut u) = unit { + u.push(unit2); + Value::Dimension(num * num2, Unit::Mul(u)) + } else if let Unit::Mul(u2) = unit2 { + let mut u = vec![unit]; + u.extend(u2); + Value::Dimension(num * num2, Unit::Mul(u)) } else { - Value::Dimension(num * num2, Unit::Mul(Box::new(unit), Box::new(unit2))) + Value::Dimension(num * num2, Unit::Mul(vec![unit, unit2])) } } + Self::BinaryOp(..) | Self::Paren(..) => { + return Self::Dimension(num, unit) * other.eval()? + } _ => { return Err( format!("Undefined operation \"{}{} * {}\".", num, unit, other).into(), @@ -219,6 +229,7 @@ impl Mul for Value { }) } } + impl Div for Value { type Output = SassResult; diff --git a/tests/units.rs b/tests/units.rs index 1582fa5..7c24626 100644 --- a/tests/units.rs +++ b/tests/units.rs @@ -34,3 +34,13 @@ test!( "a {\n color: unit(1px*1px);\n}\n", "a {\n color: \"px*px\";\n}\n" ); +test!( + unit_fn_unit_times_unit_times_unit, + "a {\n color: unit(1px * 1rad * 1em);\n}\n", + "a {\n color: \"px*rad*em\";\n}\n" +); +test!( + unit_none_times_none_times_none, + "a {\n color: 1 * 1 * 1;\n}\n", + "a {\n color: 1;\n}\n" +);