use std::cmp::Ordering;
#[derive(Debug, Clone, PartialEq)]
pub enum CompOp {
Eq,
Ne,
Lt,
Le,
Ge,
Gt
}
impl CompOp {
pub fn from_sign(sign: &str) -> Result<CompOp, ()> {
match sign.trim().as_ref() {
"==" => Ok(CompOp::Eq),
"!=" => Ok(CompOp::Ne),
"<" => Ok(CompOp::Lt),
"<=" => Ok(CompOp::Le),
">=" => Ok(CompOp::Ge),
">" => Ok(CompOp::Gt),
_ => Err(())
}
}
pub fn from_name(sign: &str) -> Result<CompOp, ()> {
match sign.trim().to_lowercase().as_ref() {
"eq" => Ok(CompOp::Eq),
"ne" => Ok(CompOp::Ne),
"lt" => Ok(CompOp::Lt),
"le" => Ok(CompOp::Le),
"ge" => Ok(CompOp::Ge),
"gt" => Ok(CompOp::Gt),
_ => Err(())
}
}
pub fn from_ord(ord: Ordering) -> CompOp {
match ord {
Ordering::Less => CompOp::Lt,
Ordering::Equal => CompOp::Eq,
Ordering::Greater => CompOp::Gt
}
}
pub fn name(&self) -> &str {
match self {
&CompOp::Eq => "eq",
&CompOp::Ne => "ne",
&CompOp::Lt => "lt",
&CompOp::Le => "le",
&CompOp::Ge => "ge",
&CompOp::Gt => "gt"
}
}
pub fn as_inverted(self) -> Self {
self.invert()
}
pub fn invert(&self) -> Self {
match self {
&CompOp::Eq => CompOp::Ne,
&CompOp::Ne => CompOp::Eq,
&CompOp::Lt => CompOp::Ge,
&CompOp::Le => CompOp::Gt,
&CompOp::Ge => CompOp::Lt,
&CompOp::Gt => CompOp::Le
}
}
pub fn as_opposite(self) -> Self {
self.opposite()
}
pub fn opposite(&self) -> Self {
match self {
&CompOp::Eq => CompOp::Ne,
&CompOp::Ne => CompOp::Eq,
&CompOp::Lt => CompOp::Gt,
&CompOp::Le => CompOp::Ge,
&CompOp::Ge => CompOp::Le,
&CompOp::Gt => CompOp::Lt
}
}
pub fn as_flipped(self) -> Self {
self.flip()
}
pub fn flip(&self) -> Self {
match self {
&CompOp::Lt => CompOp::Gt,
&CompOp::Le => CompOp::Ge,
&CompOp::Ge => CompOp::Le,
&CompOp::Gt => CompOp::Lt,
_ => self.clone()
}
}
pub fn sign(&self) -> &'static str {
match self {
&CompOp::Eq => "==",
&CompOp::Ne => "!=",
&CompOp::Lt => "<",
&CompOp::Le => "<=",
&CompOp::Ge => ">=",
&CompOp::Gt => ">"
}
}
pub fn factor(&self) -> i8 {
match self {
&CompOp::Eq | &CompOp::Ne => 0,
&CompOp::Lt | &CompOp::Le => -1,
&CompOp::Gt | &CompOp::Ge => 1
}
}
pub fn ord(&self) -> Option<Ordering> {
match self {
&CompOp::Eq => Some(Ordering::Equal),
&CompOp::Lt => Some(Ordering::Less),
&CompOp::Gt => Some(Ordering::Greater),
_ => None
}
}
}
#[cfg(test)]
mod tests {
use std::cmp::Ordering;
use super::CompOp;
#[test]
fn from_sign() {
assert_eq!(CompOp::from_sign("==").unwrap(), CompOp::Eq);
assert_eq!(CompOp::from_sign("!=").unwrap(), CompOp::Ne);
assert_eq!(CompOp::from_sign("<").unwrap(), CompOp::Lt);
assert_eq!(CompOp::from_sign("<=").unwrap(), CompOp::Le);
assert_eq!(CompOp::from_sign(">=").unwrap(), CompOp::Ge);
assert_eq!(CompOp::from_sign(">").unwrap(), CompOp::Gt);
assert_eq!(CompOp::from_sign(" <= ").unwrap(), CompOp::Le);
assert!(CompOp::from_sign("*").is_err());
}
#[test]
fn from_name() {
assert_eq!(CompOp::from_name("eq").unwrap(), CompOp::Eq);
assert_eq!(CompOp::from_name("ne").unwrap(), CompOp::Ne);
assert_eq!(CompOp::from_name("lt").unwrap(), CompOp::Lt);
assert_eq!(CompOp::from_name("le").unwrap(), CompOp::Le);
assert_eq!(CompOp::from_name("ge").unwrap(), CompOp::Ge);
assert_eq!(CompOp::from_name("gt").unwrap(), CompOp::Gt);
assert_eq!(CompOp::from_name(" Le ").unwrap(), CompOp::Le);
assert!(CompOp::from_name("abc").is_err());
}
#[test]
fn from_ord() {
assert_eq!(CompOp::from_ord(Ordering::Less), CompOp::Lt);
assert_eq!(CompOp::from_ord(Ordering::Equal), CompOp::Eq);
assert_eq!(CompOp::from_ord(Ordering::Greater), CompOp::Gt);
}
#[test]
fn name() {
assert_eq!(CompOp::Eq.name(), "eq");
assert_eq!(CompOp::Ne.name(), "ne");
assert_eq!(CompOp::Lt.name(), "lt");
assert_eq!(CompOp::Le.name(), "le");
assert_eq!(CompOp::Ge.name(), "ge");
assert_eq!(CompOp::Gt.name(), "gt");
}
#[test]
fn as_inverted() {
assert_eq!(CompOp::Ne.as_inverted(), CompOp::Eq);
assert_eq!(CompOp::Eq.as_inverted(), CompOp::Ne);
assert_eq!(CompOp::Ge.as_inverted(), CompOp::Lt);
assert_eq!(CompOp::Gt.as_inverted(), CompOp::Le);
assert_eq!(CompOp::Lt.as_inverted(), CompOp::Ge);
assert_eq!(CompOp::Le.as_inverted(), CompOp::Gt);
}
#[test]
fn invert() {
assert_eq!(CompOp::Ne.invert(), CompOp::Eq);
assert_eq!(CompOp::Eq.invert(), CompOp::Ne);
assert_eq!(CompOp::Ge.invert(), CompOp::Lt);
assert_eq!(CompOp::Gt.invert(), CompOp::Le);
assert_eq!(CompOp::Lt.invert(), CompOp::Ge);
assert_eq!(CompOp::Le.invert(), CompOp::Gt);
}
#[test]
fn as_opposite() {
assert_eq!(CompOp::Ne.as_opposite(), CompOp::Eq);
assert_eq!(CompOp::Eq.as_opposite(), CompOp::Ne);
assert_eq!(CompOp::Gt.as_opposite(), CompOp::Lt);
assert_eq!(CompOp::Ge.as_opposite(), CompOp::Le);
assert_eq!(CompOp::Le.as_opposite(), CompOp::Ge);
assert_eq!(CompOp::Lt.as_opposite(), CompOp::Gt);
}
#[test]
fn opposite() {
assert_eq!(CompOp::Eq.opposite(), CompOp::Ne);
assert_eq!(CompOp::Ne.opposite(), CompOp::Eq);
assert_eq!(CompOp::Lt.opposite(), CompOp::Gt);
assert_eq!(CompOp::Le.opposite(), CompOp::Ge);
assert_eq!(CompOp::Ge.opposite(), CompOp::Le);
assert_eq!(CompOp::Gt.opposite(), CompOp::Lt);
}
#[test]
fn as_flipped() {
assert_eq!(CompOp::Eq.as_flipped(), CompOp::Eq);
assert_eq!(CompOp::Ne.as_flipped(), CompOp::Ne);
assert_eq!(CompOp::Lt.as_flipped(), CompOp::Gt);
assert_eq!(CompOp::Le.as_flipped(), CompOp::Ge);
assert_eq!(CompOp::Ge.as_flipped(), CompOp::Le);
assert_eq!(CompOp::Gt.as_flipped(), CompOp::Lt);
}
#[test]
fn flip() {
assert_eq!(CompOp::Eq.flip(), CompOp::Eq);
assert_eq!(CompOp::Ne.flip(), CompOp::Ne);
assert_eq!(CompOp::Lt.flip(), CompOp::Gt);
assert_eq!(CompOp::Le.flip(), CompOp::Ge);
assert_eq!(CompOp::Ge.flip(), CompOp::Le);
assert_eq!(CompOp::Gt.flip(), CompOp::Lt);
}
#[test]
fn sign() {
assert_eq!(CompOp::Eq.sign(), "==");
assert_eq!(CompOp::Ne.sign(), "!=");
assert_eq!(CompOp::Lt.sign(), "<");
assert_eq!(CompOp::Le.sign(), "<=");
assert_eq!(CompOp::Ge.sign(), ">=");
assert_eq!(CompOp::Gt.sign(), ">");
}
#[test]
fn factor() {
assert_eq!(CompOp::Eq.factor(), 0);
assert_eq!(CompOp::Ne.factor(), 0);
assert_eq!(CompOp::Lt.factor(), -1);
assert_eq!(CompOp::Le.factor(), -1);
assert_eq!(CompOp::Ge.factor(), 1);
assert_eq!(CompOp::Gt.factor(), 1);
}
#[test]
fn ord() {
assert_eq!(CompOp::Eq.ord(), Some(Ordering::Equal));
assert_eq!(CompOp::Ne.ord(), None);
assert_eq!(CompOp::Lt.ord(), Some(Ordering::Less));
assert_eq!(CompOp::Le.ord(), None);
assert_eq!(CompOp::Ge.ord(), None);
assert_eq!(CompOp::Gt.ord(), Some(Ordering::Greater));
}
}