use pest_consume::Parser;
use crate::sql::expression::parser::{ExpressionParser, Result, Rule};
use crate::sql::expression::value::Value;
#[derive(Eq, PartialEq, Debug)]
pub enum ComparisonOperator {
Eq,
NotEq,
Gt,
Lt,
GtEq,
LtEq,
Contains,
IsContainedBy,
Overlap,
}
impl ComparisonOperator {
pub fn apply(&self, left: &Value, right: &Value) -> Value {
use ComparisonOperator::*;
use Value::*;
match (left, self, right) {
(Null, _, _) => Null,
(_, _, Null) => Null,
(left, Eq, right) => Boolean(left == right),
_ => unimplemented!("{:#?} {:#?} {:#?}", left, self, right),
}
}
pub fn parse(input: &str) -> Result<ComparisonOperator> {
let nodes = ExpressionParser::parse(Rule::comparison_operator, input)?;
let node = nodes.single()?;
let v = ExpressionParser::comparison_operator(node)?;
Ok(v)
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn parsing_comparison_operator() {
assert_eq!(
ComparisonOperator::parse("<>"),
Ok(ComparisonOperator::NotEq)
);
assert_eq!(
ComparisonOperator::parse("!="),
Ok(ComparisonOperator::NotEq)
);
assert_eq!(ComparisonOperator::parse(">"), Ok(ComparisonOperator::Gt));
assert_eq!(ComparisonOperator::parse("<"), Ok(ComparisonOperator::Lt));
assert_eq!(
ComparisonOperator::parse("<="),
Ok(ComparisonOperator::LtEq)
);
assert_eq!(
ComparisonOperator::parse(">="),
Ok(ComparisonOperator::GtEq)
);
assert_eq!(
ComparisonOperator::parse("@>"),
Ok(ComparisonOperator::Contains)
);
assert_eq!(
ComparisonOperator::parse("<@"),
Ok(ComparisonOperator::IsContainedBy)
);
assert_eq!(
ComparisonOperator::parse("&&"),
Ok(ComparisonOperator::Overlap)
);
assert!(ComparisonOperator::parse("~~>").is_err());
}
}