use core::fmt::{self, Write};
use crate::operand::Operand;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Comparison {
pub(crate) left: Operand,
pub(crate) cmp: Comparator,
pub(crate) right: Operand,
}
impl fmt::Display for Comparison {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.left.fmt(f)?;
f.write_char(' ')?;
self.cmp.fmt(f)?;
f.write_char(' ')?;
self.right.fmt(f)
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum Comparator {
Eq,
Ne,
Lt,
Le,
Gt,
Ge,
}
impl Comparator {
pub fn as_str(self) -> &'static str {
match self {
Self::Eq => "=",
Self::Ne => "<>",
Self::Lt => "<",
Self::Le => "<=",
Self::Gt => ">",
Self::Ge => ">=",
}
}
}
impl fmt::Display for Comparator {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
}
}
pub fn equal<L, R>(left: L, right: R) -> Comparison
where
L: Into<Operand>,
R: Into<Operand>,
{
Comparison {
left: left.into(),
cmp: Comparator::Eq,
right: right.into(),
}
}
pub fn not_equal<L, R>(left: L, right: R) -> Comparison
where
L: Into<Operand>,
R: Into<Operand>,
{
Comparison {
left: left.into(),
cmp: Comparator::Ne,
right: right.into(),
}
}
pub fn greater_than<L, R>(left: L, right: R) -> Comparison
where
L: Into<Operand>,
R: Into<Operand>,
{
Comparison {
left: left.into(),
cmp: Comparator::Gt,
right: right.into(),
}
}
pub fn greater_than_or_equal<L, R>(left: L, right: R) -> Comparison
where
L: Into<Operand>,
R: Into<Operand>,
{
Comparison {
left: left.into(),
cmp: Comparator::Ge,
right: right.into(),
}
}
pub fn less_than<L, R>(left: L, right: R) -> Comparison
where
L: Into<Operand>,
R: Into<Operand>,
{
Comparison {
left: left.into(),
cmp: Comparator::Lt,
right: right.into(),
}
}
pub fn less_than_or_equal<L, R>(left: L, right: R) -> Comparison
where
L: Into<Operand>,
R: Into<Operand>,
{
Comparison {
left: left.into(),
cmp: Comparator::Le,
right: right.into(),
}
}
#[cfg(test)]
mod test {
use pretty_assertions::assert_str_eq;
use crate::path::Name;
use super::{Comparator::*, *};
#[test]
fn display() {
assert_str_eq!("=", Eq.to_string());
assert_str_eq!("<>", Ne.to_string());
assert_str_eq!("<", Lt.to_string());
assert_str_eq!("<=", Le.to_string());
assert_str_eq!(">", Gt.to_string());
assert_str_eq!(">=", Ge.to_string());
}
#[test]
fn eq() {
assert_eq!(
"foo = bar",
equal(Name::from("foo"), Name::from("bar")).to_string()
);
}
#[test]
fn ne() {
assert_eq!(
"foo <> bar",
not_equal(Name::from("foo"), Name::from("bar")).to_string()
);
}
#[test]
fn lt() {
assert_eq!(
"foo < bar",
less_than(Name::from("foo"), Name::from("bar")).to_string()
);
}
#[test]
fn le() {
assert_eq!(
"foo <= bar",
less_than_or_equal(Name::from("foo"), Name::from("bar")).to_string()
);
}
#[test]
fn gt() {
assert_eq!(
"foo > bar",
greater_than(Name::from("foo"), Name::from("bar")).to_string()
);
}
#[test]
fn ge() {
assert_eq!(
"foo >= bar",
greater_than_or_equal(Name::from("foo"), Name::from("bar")).to_string()
);
}
}