implement > < >= <=
This commit is contained in:
parent
211a57ebdb
commit
2ce639e9be
@ -1,10 +1,11 @@
|
||||
use std::fmt::{self, Display, Write};
|
||||
use std::iter::Iterator;
|
||||
use std::cmp::Ordering;
|
||||
|
||||
use crate::color::Color;
|
||||
use crate::common::{Brackets, ListSeparator, Op, QuoteKind};
|
||||
use crate::error::SassResult;
|
||||
use crate::unit::Unit;
|
||||
use crate::unit::{Unit, UNIT_CONVERSION_TABLE};
|
||||
pub(crate) use number::Number;
|
||||
|
||||
mod number;
|
||||
@ -183,7 +184,22 @@ impl Value {
|
||||
Op::Mul => *lhs * *rhs,
|
||||
Op::Div => *lhs / *rhs,
|
||||
Op::Rem => *lhs % *rhs,
|
||||
_ => Ok(Self::BinaryOp(lhs, op, rhs)),
|
||||
Op::GreaterThan => match lhs.cmp(&rhs, op)? {
|
||||
Ordering::Greater => Ok(Self::True),
|
||||
Ordering::Less | Ordering::Equal=> Ok(Self::False),
|
||||
},
|
||||
Op::GreaterThanEqual => match lhs.cmp(&rhs, op)? {
|
||||
Ordering::Greater | Ordering::Equal => Ok(Self::True),
|
||||
Ordering::Less => Ok(Self::False),
|
||||
},
|
||||
Op::LessThan => match lhs.cmp(&rhs, op)? {
|
||||
Ordering::Less => Ok(Self::True),
|
||||
Ordering::Greater | Ordering::Equal=> Ok(Self::False),
|
||||
},
|
||||
Op::LessThanEqual => match lhs.cmp(&rhs, op)? {
|
||||
Ordering::Less | Ordering::Equal => Ok(Self::True),
|
||||
Ordering::Greater => Ok(Self::False),
|
||||
},
|
||||
},
|
||||
Self::Paren(v) => v.eval(),
|
||||
Self::UnaryOp(op, val) => match op {
|
||||
@ -194,4 +210,27 @@ impl Value {
|
||||
_ => Ok(self),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cmp(&self, other: &Self, op: Op) -> SassResult<Ordering> {
|
||||
Ok(match self {
|
||||
Self::Dimension(num, ref unit) => match other {
|
||||
Self::Dimension(num2, unit2) => {
|
||||
if !unit.comparable(&unit2) {
|
||||
return Err(format!("Incompatible units {} and {}.", unit2, unit).into());
|
||||
}
|
||||
if unit == unit2 {
|
||||
num.cmp(num2)
|
||||
} else if unit == &Unit::None {
|
||||
num.cmp(num2)
|
||||
} else if unit2 == &Unit::None {
|
||||
num.cmp(num2)
|
||||
} else {
|
||||
num.cmp(&(num2.clone() * UNIT_CONVERSION_TABLE[&unit.to_string()][&unit2.to_string()].clone()))
|
||||
}
|
||||
}
|
||||
_ => return Err(format!("Undefined operation \"{} {} {}\".", self, op, other).into()),
|
||||
},
|
||||
_ => return Err(format!("Undefined operation \"{} {} {}\".", self, op, other).into())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -188,6 +188,26 @@ impl Value {
|
||||
return Err("expected \"=\".".into());
|
||||
}
|
||||
}
|
||||
q @ '>' | q @ '<' => {
|
||||
toks.next();
|
||||
let op = if toks.peek().unwrap().kind == '=' {
|
||||
toks.next();
|
||||
match q {
|
||||
'>' => Op::GreaterThanEqual,
|
||||
'<' => Op::LessThanEqual,
|
||||
_ => unreachable!()
|
||||
}
|
||||
} else {
|
||||
match q {
|
||||
'>' => Op::GreaterThan,
|
||||
'<' => Op::LessThan,
|
||||
_ => unreachable!()
|
||||
}
|
||||
};
|
||||
devour_whitespace(toks);
|
||||
let right = Self::from_tokens(toks, scope, super_selector)?;
|
||||
Ok(Value::BinaryOp(Box::new(left), op, Box::new(right)))
|
||||
}
|
||||
'!' => {
|
||||
toks.next();
|
||||
if toks.peek().unwrap().kind == '=' {
|
||||
|
65
tests/ordering.rs
Normal file
65
tests/ordering.rs
Normal file
@ -0,0 +1,65 @@
|
||||
#![cfg(test)]
|
||||
|
||||
#[macro_use]
|
||||
mod macros;
|
||||
|
||||
test!(
|
||||
greater_than_or_equal_is_greater,
|
||||
"a {\n color: 2 >= 1;\n}\n",
|
||||
"a {\n color: true;\n}\n"
|
||||
);
|
||||
test!(
|
||||
greater_than_or_equal_is_equal,
|
||||
"a {\n color: 1 >= 1;\n}\n",
|
||||
"a {\n color: true;\n}\n"
|
||||
);
|
||||
test!(
|
||||
greater_than_or_equal_is_less,
|
||||
"a {\n color: 0 >= 1;\n}\n",
|
||||
"a {\n color: false;\n}\n"
|
||||
);
|
||||
test!(
|
||||
greater_than_is_greater,
|
||||
"a {\n color: 2 > 1;\n}\n",
|
||||
"a {\n color: true;\n}\n"
|
||||
);
|
||||
test!(
|
||||
greater_than_is_equal,
|
||||
"a {\n color: 1 > 1;\n}\n",
|
||||
"a {\n color: false;\n}\n"
|
||||
);
|
||||
test!(
|
||||
greater_than_is_less,
|
||||
"a {\n color: 0 > 1;\n}\n",
|
||||
"a {\n color: false;\n}\n"
|
||||
);
|
||||
test!(
|
||||
less_than_or_equal_is_greater,
|
||||
"a {\n color: 2 <= 1;\n}\n",
|
||||
"a {\n color: false;\n}\n"
|
||||
);
|
||||
test!(
|
||||
less_than_or_equal_is_equal,
|
||||
"a {\n color: 1 <= 1;\n}\n",
|
||||
"a {\n color: true;\n}\n"
|
||||
);
|
||||
test!(
|
||||
less_than_or_equal_is_less,
|
||||
"a {\n color: 0 <= 1;\n}\n",
|
||||
"a {\n color: true;\n}\n"
|
||||
);
|
||||
test!(
|
||||
less_than_is_greater,
|
||||
"a {\n color: 2 < 1;\n}\n",
|
||||
"a {\n color: false;\n}\n"
|
||||
);
|
||||
test!(
|
||||
less_than_is_equal,
|
||||
"a {\n color: 1 < 1;\n}\n",
|
||||
"a {\n color: false;\n}\n"
|
||||
);
|
||||
test!(
|
||||
less_than_is_less,
|
||||
"a {\n color: 0 < 1;\n}\n",
|
||||
"a {\n color: true;\n}\n"
|
||||
);
|
Loading…
x
Reference in New Issue
Block a user