use anyhow::bail;
use std::fmt::Display;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Operator {
Minus,
Plus,
Concat,
Asterisk,
Slash,
Percent,
Eq,
Neq,
Lt,
Lte,
Gt,
Gte,
Not,
And,
Or,
In,
NotIn,
Is,
IsNot,
Like,
Range,
}
impl Operator {
pub fn of(expression: &str) -> anyhow::Result<Self> {
match expression {
"-" => Ok(Self::Minus),
"+" => Ok(Self::Plus),
"||" => Ok(Self::Concat),
"*" => Ok(Self::Asterisk),
"/" => Ok(Self::Slash),
"%" => Ok(Self::Percent),
"==" => Ok(Self::Eq),
"!=" => Ok(Self::Neq),
"<>" => Ok(Self::Neq),
"<" => Ok(Self::Lt),
"<=" => Ok(Self::Lte),
">" => Ok(Self::Gt),
">=" => Ok(Self::Gte),
"NOT" => Ok(Self::Not),
"AND" => Ok(Self::And),
"OR" => Ok(Self::Or),
"IN" => Ok(Self::In),
"NOT IN" => Ok(Self::NotIn),
"IS" => Ok(Self::Is),
"IS NOT" => Ok(Self::IsNot),
"LIKE" => Ok(Self::Like),
".." => Ok(Self::Range),
_ => bail!("Unknown operator: {}", expression),
}
}
pub fn str(&self) -> &'static str {
match self {
Self::Minus => "-",
Self::Plus => "+",
Self::Concat => "||",
Self::Asterisk => "*",
Self::Slash => "/",
Self::Percent => "%",
Self::Eq => "==",
Self::Neq => "!=",
Self::Lt => "<",
Self::Lte => "<=",
Self::Gt => ">",
Self::Gte => ">=",
Self::Not => "NOT",
Self::And => "AND",
Self::Or => "OR",
Self::In => "IN",
Self::NotIn => "NOT IN",
Self::Is => "IS",
Self::IsNot => "IS NOT",
Self::Like => "LIKE",
Self::Range => "..",
}
}
}
impl Display for Operator {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.str())
}
}