Support arbitrary amount of numbers multiplied together

This commit is contained in:
ConnorSkees 2020-03-17 10:06:24 -04:00
parent f57b08069d
commit 3b5dd73a65
3 changed files with 41 additions and 5 deletions

View File

@ -92,8 +92,8 @@ pub(crate) enum Unit {
/// Unspecified unit /// Unspecified unit
None, None,
/// Two units multiplied together /// Units multiplied together
Mul(Box<Unit>, Box<Unit>), Mul(Vec<Unit>),
/// A unit divided by another /// A unit divided by another
Div(Box<Unit>, Box<Unit>), Div(Box<Unit>, Box<Unit>),
} }
@ -228,7 +228,15 @@ impl Into<String> for Unit {
Unit::X => "x", Unit::X => "x",
Unit::Fr => "fr", Unit::Fr => "fr",
Unit::None => "", Unit::None => "",
Unit::Mul(l, r) => return format!("{}*{}", l, r), Unit::Mul(u) => {
return format!(
"{}",
u.into_iter()
.map(|x| x.to_string())
.collect::<Vec<String>>()
.join("*")
)
}
Unit::Div(l, r) => return format!("{}/{}", l, r), Unit::Div(l, r) => return format!("{}/{}", l, r),
Unit::Unknown(ref s) => s, Unit::Unknown(ref s) => s,
} }
@ -276,7 +284,14 @@ impl fmt::Display for Unit {
Unit::Fr => write!(f, "fr"), Unit::Fr => write!(f, "fr"),
Unit::Unknown(s) => write!(f, "{}", s), Unit::Unknown(s) => write!(f, "{}", s),
Unit::None => write!(f, ""), 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::<Vec<String>>()
.join("*")
),
Unit::Div(l, r) => write!(f, "{}/{}", l, r), Unit::Div(l, r) => write!(f, "{}/{}", l, r),
} }
} }

View File

@ -204,10 +204,20 @@ impl Mul for Value {
Value::Dimension(num * num2, unit2) Value::Dimension(num * num2, unit2)
} else if unit2 == Unit::None { } else if unit2 == Unit::None {
Value::Dimension(num * num2, unit) 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 { } 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( return Err(
format!("Undefined operation \"{}{} * {}\".", num, unit, other).into(), format!("Undefined operation \"{}{} * {}\".", num, unit, other).into(),
@ -219,6 +229,7 @@ impl Mul for Value {
}) })
} }
} }
impl Div for Value { impl Div for Value {
type Output = SassResult<Self>; type Output = SassResult<Self>;

View File

@ -34,3 +34,13 @@ test!(
"a {\n color: unit(1px*1px);\n}\n", "a {\n color: unit(1px*1px);\n}\n",
"a {\n color: \"px*px\";\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"
);