v_eval 0.0.1

Evaluator with context
Documentation
use std::cmp::Ordering;

#[derive(Debug, Clone, Copy, PartialEq)]
#[repr(u8)]
pub(super) enum Operator {
    ParenLeft = 1 << 1,
    ParenRight = (1 << 1) + 1,

    Not = 1 << 2,
    Neg = (1 << 2) + 1,

    Mul = 1 << 3,
    Div = (1 << 3) + 1,
    Rem = (1 << 3) + 2,

    Add = 1 << 4,
    Sub = (1 << 4) + 1,

    Eq = 1 << 5,
    Ne = (1 << 5) + 1,
    Gt = (1 << 5) + 2,
    Lt = (1 << 5) + 3,
    Ge = (1 << 5) + 4,
    Le = (1 << 5) + 5,

    And = 1 << 6,
    Or = (1 << 6) + 1,
}

impl Operator {
    fn preference(&self, o: &Operator) -> Ordering {
        (*self as u8)
            .leading_zeros()
            .cmp(&(*o as u8).leading_zeros())
    }

    pub(super) fn gt_preference(&self, o: &Operator) -> bool {
        match self.preference(o) {
            Ordering::Greater => true,
            _ => false,
        }
    }

    pub(super) fn eq_preference(&self, o: &Operator) -> bool {
        match self.preference(o) {
            Ordering::Equal => true,
            _ => false,
        }
    }
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn test_op_preference() {
        assert!(!Operator::Add.gt_preference(&Operator::Sub) && Operator::Sub != Operator::Add);
        assert!(!Operator::Not.gt_preference(&Operator::Not) && Operator::Not == Operator::Not);
        assert!(!Operator::Add.gt_preference(&Operator::Not));
        assert!(Operator::Not.gt_preference(&Operator::Add));
    }
}