#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
#[repr(u8)]
#[derive(Default)]
pub enum Precedence {
#[default]
Lowest = 1,
Or = 2,
And = 3,
Not = 4,
Equals = 5,
LessGreater = 6,
BitwiseOr = 7,
BitwiseXor = 8,
BitwiseAnd = 9,
BitwiseShift = 10,
Sum = 11,
Product = 12,
Prefix = 13,
Call = 14,
Index = 15,
Dot = 16,
}
impl Precedence {
pub fn for_operator(op: &str) -> Precedence {
match op.to_uppercase().as_str() {
"OR" => Precedence::Or,
"XOR" => Precedence::Or, "AND" => Precedence::And,
"NOT" => Precedence::Not,
"=" | "<>" | "!=" | "IS" | "LIKE" | "ILIKE" | "GLOB" | "REGEXP" | "RLIKE" | "IN"
| "BETWEEN" => Precedence::Equals,
"AS" => Precedence::Lowest,
"<" | ">" | "<=" | ">=" | "<=>" => Precedence::LessGreater,
"|" => Precedence::BitwiseOr,
"^" => Precedence::BitwiseXor,
"&" => Precedence::BitwiseAnd,
"<<" | ">>" => Precedence::BitwiseShift,
"+" | "-" | "||" => Precedence::Sum,
"*" | "/" | "%" => Precedence::Product,
"." => Precedence::Dot,
"(" => Precedence::Call,
"[" => Precedence::Index,
"->" | "->>" => Precedence::Index,
_ => Precedence::Lowest,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_precedence_ordering() {
assert!(Precedence::Product > Precedence::Sum);
assert!(Precedence::Sum > Precedence::LessGreater);
assert!(Precedence::LessGreater > Precedence::Equals);
assert!(Precedence::And > Precedence::Or);
assert!(Precedence::Dot > Precedence::Call);
}
#[test]
fn test_operator_precedence() {
assert_eq!(Precedence::for_operator("+"), Precedence::Sum);
assert_eq!(Precedence::for_operator("*"), Precedence::Product);
assert_eq!(Precedence::for_operator("AND"), Precedence::And);
assert_eq!(Precedence::for_operator("OR"), Precedence::Or);
assert_eq!(Precedence::for_operator("="), Precedence::Equals);
assert_eq!(Precedence::for_operator("."), Precedence::Dot);
}
}