use std::str::FromStr;
use serde_json::Value;
use crate::to_value;
use crate::error::Error;
use crate::node::Node;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Operator {
Add(u8),
Mul(u8),
Sub(u8),
Div(u8),
Rem(u8),
Not(u8),
Eq(u8),
Ne(u8),
Gt(u8),
Lt(u8),
Ge(u8),
Le(u8),
And(u8),
Or(u8),
Dot(u8),
LeftParenthesis,
RightParenthesis,
LeftSquareBracket(u8),
RightSquareBracket,
DoubleQuotes,
SingleQuote,
WhiteSpace,
Comma,
Function(String),
Identifier(String),
Value(Value),
}
impl Operator {
pub fn is_identifier(&self) -> bool {
matches!(self, Operator::Identifier(_))
}
pub fn can_at_beginning(&self) -> bool {
matches!(self, Operator::Not(_) | Operator::Function(_) | Operator::LeftParenthesis)
}
pub fn get_max_args(&self) -> Option<usize> {
match *self {
Self::Add(_) | Self::Sub(_) | Self::Mul(_) | Self::Div(_) |
Self::Eq(_) | Self::Ne(_) | Self::Gt(_) | Self::Lt(_) |
Self::Ge(_) | Self::Le(_) | Self::And(_) | Self::Or(_) |
Self::Rem(_) => Some(2),
Self::Not(_) => Some(1),
Self::Function(_) => None,
_ => Some(0),
}
}
pub fn get_min_args(&self) -> Option<usize> {
match *self {
Self::Add(_) | Self::Sub(_) | Self::Mul(_) | Self::Div(_) |
Self::Eq(_) | Self::Ne(_) | Self::Gt(_) | Self::Lt(_) |
Self::Ge(_) | Self::Le(_) | Self::And(_) | Self::Or(_) |
Self::Rem(_) => Some(2),
Self::Not(_) => Some(1),
Self::Function(_) => None,
_ => Some(0),
}
}
pub fn get_priority(&self) -> u8 {
match *self {
Self::Add(priority) |
Self::Sub(priority) |
Self::Div(priority) |
Self::Mul(priority) |
Self::Eq(priority) |
Self::Ne(priority) |
Self::Gt(priority) |
Self::Lt(priority) |
Self::Ge(priority) |
Self::Le(priority) |
Self::And(priority) |
Self::Or(priority) |
Self::Rem(priority) => priority,
Self::Value(_) |
Self::Identifier(_) => 0,
_ => 99,
}
}
pub fn is_left_parenthesis(&self) -> bool {
*self == Operator::LeftParenthesis
}
pub fn is_not(&self) -> bool {
matches!(self, Operator::Not(_))
}
pub fn is_left_square_bracket(&self) -> bool {
matches!(self, Operator::LeftSquareBracket(_))
}
pub fn is_dot(&self) -> bool {
matches!(self, Operator::Dot(_))
}
pub fn is_value_or_ident(&self) -> bool {
matches!(self, Operator::Value(_) | Operator::Identifier(_))
}
pub fn can_have_child(&self) -> bool {
matches!(self,
Operator::Function(_)
| Operator::Add(_)
| Operator::Sub(_)
| Operator::Div(_)
| Operator::Mul(_)
| Operator::Rem(_)
| Operator::Eq(_)
| Operator::Ne(_)
| Operator::Gt(_)
| Operator::Lt(_)
| Operator::And(_)
| Operator::Or(_)
| Operator::Ge(_)
| Operator::Not(_)
| Operator::Dot(_)
| Operator::LeftSquareBracket(_)
| Operator::Le(_)
)
}
pub fn is_left(&self) -> bool {
matches!(self, Operator::LeftParenthesis | Operator::LeftSquareBracket(_))
}
pub fn get_left(&self) -> Operator {
match *self {
Self::RightParenthesis => Self::LeftParenthesis,
Self::RightSquareBracket => Self::LeftSquareBracket(100),
_ => panic!("not bracket"),
}
}
pub fn to_node(&self) -> Node {
Node::new(self.clone())
}
pub fn children_to_node(&self, children: Vec<Node>) -> Node {
let mut node = self.to_node();
node.children = children;
node
}
pub fn get_identifier(&self) -> &str {
match *self {
Self::Identifier(ref ident) => ident,
_ => panic!("not identifier"),
}
}
}
impl FromStr for Operator {
type Err = Error;
fn from_str(raw: &str) -> Result<Self, Error> {
match raw {
"+" => Ok(Self::Add(8)),
"-" => Ok(Self::Sub(8)),
"*" => Ok(Self::Mul(10)),
"/" => Ok(Self::Div(10)),
"%" => Ok(Self::Rem(10)),
"(" => Ok(Self::LeftParenthesis),
")" => Ok(Self::RightParenthesis),
"[" => Ok(Self::LeftSquareBracket(100)),
"]" => Ok(Self::RightSquareBracket),
"." => Ok(Self::Dot(100)),
"\"" => Ok(Self::DoubleQuotes),
"'" => Ok(Self::SingleQuote),
" " => Ok(Self::WhiteSpace),
"," => Ok(Self::Comma),
"!" => Ok(Self::Not(99)),
"false" => Ok(Self::Value(to_value(false))),
"true" => Ok(Self::Value(to_value(true))),
"==" => Ok(Self::Eq(6)),
"!=" => Ok(Self::Ne(6)),
">" => Ok(Self::Gt(6)),
"<" => Ok(Self::Lt(6)),
">=" => Ok(Self::Ge(6)),
"<=" => Ok(Self::Le(6)),
"&&" => Ok(Self::And(4)),
"||" => Ok(Self::Or(2)),
_ => Ok(Self::Identifier(raw.to_owned())),
}
}
}