2022-01-13 17:36:41 +00:00
|
|
|
|
use crate::sql::comment::mightbespace;
|
|
|
|
|
use crate::sql::comment::shouldbespace;
|
2022-01-16 20:31:50 +00:00
|
|
|
|
use crate::sql::error::IResult;
|
2020-06-29 15:36:01 +00:00
|
|
|
|
use nom::branch::alt;
|
|
|
|
|
use nom::bytes::complete::tag;
|
|
|
|
|
use nom::bytes::complete::tag_no_case;
|
2022-03-16 23:52:25 +00:00
|
|
|
|
use nom::character::complete::char;
|
2020-06-29 15:36:01 +00:00
|
|
|
|
use nom::combinator::map;
|
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
|
use std::fmt;
|
|
|
|
|
|
2022-10-27 12:23:24 +00:00
|
|
|
|
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
|
2020-06-29 15:36:01 +00:00
|
|
|
|
pub enum Operator {
|
2022-12-02 21:48:10 +00:00
|
|
|
|
//
|
2020-06-29 15:36:01 +00:00
|
|
|
|
Or, // ||
|
2021-03-29 15:43:37 +00:00
|
|
|
|
And, // &&
|
2022-12-02 21:48:10 +00:00
|
|
|
|
Tco, // ?: Ternary conditional operator
|
|
|
|
|
Nco, // ?? Null coalescing operator
|
2020-06-29 15:36:01 +00:00
|
|
|
|
//
|
|
|
|
|
Add, // +
|
|
|
|
|
Sub, // -
|
|
|
|
|
Mul, // *
|
|
|
|
|
Div, // /
|
2022-12-18 14:56:07 +00:00
|
|
|
|
Pow, // **
|
2020-06-29 15:36:01 +00:00
|
|
|
|
Inc, // +=
|
|
|
|
|
Dec, // -=
|
|
|
|
|
//
|
|
|
|
|
Equal, // =
|
2022-12-02 21:48:10 +00:00
|
|
|
|
Exact, // ==
|
2020-06-29 15:36:01 +00:00
|
|
|
|
NotEqual, // !=
|
|
|
|
|
AllEqual, // *=
|
|
|
|
|
AnyEqual, // ?=
|
|
|
|
|
//
|
|
|
|
|
Like, // ~
|
|
|
|
|
NotLike, // !~
|
|
|
|
|
AllLike, // *~
|
|
|
|
|
AnyLike, // ?~
|
|
|
|
|
//
|
|
|
|
|
LessThan, // <
|
|
|
|
|
LessThanOrEqual, // <=
|
|
|
|
|
MoreThan, // >
|
|
|
|
|
MoreThanOrEqual, // >=
|
|
|
|
|
//
|
|
|
|
|
Contain, // ∋
|
|
|
|
|
NotContain, // ∌
|
|
|
|
|
ContainAll, // ⊇
|
2022-01-13 17:36:41 +00:00
|
|
|
|
ContainAny, // ⊃
|
2020-06-29 15:36:01 +00:00
|
|
|
|
ContainNone, // ⊅
|
|
|
|
|
Inside, // ∈
|
|
|
|
|
NotInside, // ∉
|
|
|
|
|
AllInside, // ⊆
|
2022-01-13 17:36:41 +00:00
|
|
|
|
AnyInside, // ⊂
|
2020-06-29 15:36:01 +00:00
|
|
|
|
NoneInside, // ⊄
|
2022-11-03 10:59:01 +00:00
|
|
|
|
//
|
|
|
|
|
Outside,
|
|
|
|
|
Intersects,
|
2020-06-29 15:36:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Default for Operator {
|
2022-10-04 21:51:18 +00:00
|
|
|
|
fn default() -> Self {
|
|
|
|
|
Self::Equal
|
2020-06-29 15:36:01 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-13 00:18:23 +00:00
|
|
|
|
impl Operator {
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn precedence(&self) -> u8 {
|
|
|
|
|
match self {
|
|
|
|
|
Operator::Or => 1,
|
|
|
|
|
Operator::And => 2,
|
2022-12-02 21:48:10 +00:00
|
|
|
|
Operator::Tco => 3,
|
|
|
|
|
Operator::Nco => 4,
|
|
|
|
|
Operator::Sub => 6,
|
|
|
|
|
Operator::Add => 7,
|
|
|
|
|
Operator::Mul => 8,
|
|
|
|
|
Operator::Div => 9,
|
|
|
|
|
_ => 5,
|
2022-03-13 00:18:23 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-29 15:36:01 +00:00
|
|
|
|
impl fmt::Display for Operator {
|
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2022-09-27 21:35:30 +00:00
|
|
|
|
f.write_str(match self {
|
2022-10-04 21:51:18 +00:00
|
|
|
|
Self::Or => "OR",
|
|
|
|
|
Self::And => "AND",
|
2022-12-02 21:48:10 +00:00
|
|
|
|
Self::Tco => "?:",
|
|
|
|
|
Self::Nco => "??",
|
2022-10-04 21:51:18 +00:00
|
|
|
|
Self::Add => "+",
|
|
|
|
|
Self::Sub => "-",
|
|
|
|
|
Self::Mul => "*",
|
|
|
|
|
Self::Div => "/",
|
2022-12-18 14:56:07 +00:00
|
|
|
|
Self::Pow => "**",
|
2022-10-04 21:51:18 +00:00
|
|
|
|
Self::Inc => "+=",
|
|
|
|
|
Self::Dec => "-=",
|
|
|
|
|
Self::Equal => "=",
|
2022-12-02 21:48:10 +00:00
|
|
|
|
Self::Exact => "==",
|
2022-10-04 21:51:18 +00:00
|
|
|
|
Self::NotEqual => "!=",
|
|
|
|
|
Self::AllEqual => "*=",
|
|
|
|
|
Self::AnyEqual => "?=",
|
|
|
|
|
Self::Like => "~",
|
|
|
|
|
Self::NotLike => "!~",
|
|
|
|
|
Self::AllLike => "*~",
|
|
|
|
|
Self::AnyLike => "?~",
|
|
|
|
|
Self::LessThan => "<",
|
|
|
|
|
Self::LessThanOrEqual => "<=",
|
|
|
|
|
Self::MoreThan => ">",
|
|
|
|
|
Self::MoreThanOrEqual => ">=",
|
|
|
|
|
Self::Contain => "CONTAINS",
|
|
|
|
|
Self::NotContain => "CONTAINSNOT",
|
|
|
|
|
Self::ContainAll => "CONTAINSALL",
|
|
|
|
|
Self::ContainAny => "CONTAINSANY",
|
|
|
|
|
Self::ContainNone => "CONTAINSNONE",
|
|
|
|
|
Self::Inside => "INSIDE",
|
|
|
|
|
Self::NotInside => "NOTINSIDE",
|
|
|
|
|
Self::AllInside => "ALLINSIDE",
|
|
|
|
|
Self::AnyInside => "ANYINSIDE",
|
|
|
|
|
Self::NoneInside => "NONEINSIDE",
|
|
|
|
|
Self::Outside => "OUTSIDE",
|
|
|
|
|
Self::Intersects => "INTERSECTS",
|
2022-09-27 21:35:30 +00:00
|
|
|
|
})
|
2020-06-29 15:36:01 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn assigner(i: &str) -> IResult<&str, Operator> {
|
|
|
|
|
alt((
|
2022-03-16 23:52:25 +00:00
|
|
|
|
map(char('='), |_| Operator::Equal),
|
2020-06-29 15:36:01 +00:00
|
|
|
|
map(tag("+="), |_| Operator::Inc),
|
|
|
|
|
map(tag("-="), |_| Operator::Dec),
|
|
|
|
|
))(i)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn operator(i: &str) -> IResult<&str, Operator> {
|
2022-01-13 17:36:41 +00:00
|
|
|
|
alt((symbols, phrases))(i)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn symbols(i: &str) -> IResult<&str, Operator> {
|
|
|
|
|
let (i, _) = mightbespace(i)?;
|
|
|
|
|
let (i, v) = alt((
|
2022-12-02 21:48:10 +00:00
|
|
|
|
alt((
|
|
|
|
|
map(tag("||"), |_| Operator::Or),
|
|
|
|
|
map(tag("&&"), |_| Operator::And),
|
|
|
|
|
map(tag("?:"), |_| Operator::Tco),
|
|
|
|
|
map(tag("??"), |_| Operator::Nco),
|
|
|
|
|
)),
|
2020-06-29 15:36:01 +00:00
|
|
|
|
alt((
|
2021-05-17 17:00:17 +00:00
|
|
|
|
map(tag("=="), |_| Operator::Exact),
|
2020-06-29 15:36:01 +00:00
|
|
|
|
map(tag("!="), |_| Operator::NotEqual),
|
|
|
|
|
map(tag("*="), |_| Operator::AllEqual),
|
|
|
|
|
map(tag("?="), |_| Operator::AnyEqual),
|
2022-03-16 23:52:25 +00:00
|
|
|
|
map(char('='), |_| Operator::Equal),
|
2020-06-29 15:36:01 +00:00
|
|
|
|
)),
|
|
|
|
|
alt((
|
|
|
|
|
map(tag("!~"), |_| Operator::NotLike),
|
|
|
|
|
map(tag("*~"), |_| Operator::AllLike),
|
|
|
|
|
map(tag("?~"), |_| Operator::AnyLike),
|
2022-03-16 23:52:25 +00:00
|
|
|
|
map(char('~'), |_| Operator::Like),
|
2020-06-29 15:36:01 +00:00
|
|
|
|
)),
|
|
|
|
|
alt((
|
|
|
|
|
map(tag("<="), |_| Operator::LessThanOrEqual),
|
2022-03-16 23:52:25 +00:00
|
|
|
|
map(char('<'), |_| Operator::LessThan),
|
2020-06-29 15:36:01 +00:00
|
|
|
|
map(tag(">="), |_| Operator::MoreThanOrEqual),
|
2022-03-16 23:52:25 +00:00
|
|
|
|
map(char('>'), |_| Operator::MoreThan),
|
2020-06-29 15:36:01 +00:00
|
|
|
|
)),
|
2021-05-22 18:18:02 +00:00
|
|
|
|
alt((
|
2022-12-27 11:47:41 +00:00
|
|
|
|
map(tag("**"), |_| Operator::Pow),
|
2022-03-16 23:52:25 +00:00
|
|
|
|
map(char('+'), |_| Operator::Add),
|
|
|
|
|
map(char('-'), |_| Operator::Sub),
|
|
|
|
|
map(char('*'), |_| Operator::Mul),
|
|
|
|
|
map(char('×'), |_| Operator::Mul),
|
|
|
|
|
map(char('∙'), |_| Operator::Mul),
|
|
|
|
|
map(char('/'), |_| Operator::Div),
|
|
|
|
|
map(char('÷'), |_| Operator::Div),
|
2021-05-22 18:18:02 +00:00
|
|
|
|
)),
|
2020-06-29 15:36:01 +00:00
|
|
|
|
alt((
|
2022-03-16 23:52:25 +00:00
|
|
|
|
map(char('∋'), |_| Operator::Contain),
|
|
|
|
|
map(char('∌'), |_| Operator::NotContain),
|
|
|
|
|
map(char('∈'), |_| Operator::Inside),
|
|
|
|
|
map(char('∉'), |_| Operator::NotInside),
|
|
|
|
|
map(char('⊇'), |_| Operator::ContainAll),
|
|
|
|
|
map(char('⊃'), |_| Operator::ContainAny),
|
|
|
|
|
map(char('⊅'), |_| Operator::ContainNone),
|
|
|
|
|
map(char('⊆'), |_| Operator::AllInside),
|
|
|
|
|
map(char('⊂'), |_| Operator::AnyInside),
|
|
|
|
|
map(char('⊄'), |_| Operator::NoneInside),
|
2020-06-29 15:36:01 +00:00
|
|
|
|
)),
|
2022-01-13 17:36:41 +00:00
|
|
|
|
))(i)?;
|
|
|
|
|
let (i, _) = mightbespace(i)?;
|
|
|
|
|
Ok((i, v))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn phrases(i: &str) -> IResult<&str, Operator> {
|
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
|
let (i, v) = alt((
|
2020-06-29 15:36:01 +00:00
|
|
|
|
alt((
|
|
|
|
|
map(tag_no_case("OR"), |_| Operator::Or),
|
2022-12-02 21:48:10 +00:00
|
|
|
|
map(tag_no_case("AND"), |_| Operator::And),
|
2020-06-29 15:36:01 +00:00
|
|
|
|
map(tag_no_case("IS NOT"), |_| Operator::NotEqual),
|
|
|
|
|
map(tag_no_case("IS"), |_| Operator::Equal),
|
|
|
|
|
)),
|
|
|
|
|
alt((
|
2022-06-28 13:39:07 +00:00
|
|
|
|
map(tag_no_case("CONTAINSALL"), |_| Operator::ContainAll),
|
|
|
|
|
map(tag_no_case("CONTAINSANY"), |_| Operator::ContainAny),
|
|
|
|
|
map(tag_no_case("CONTAINSNONE"), |_| Operator::ContainNone),
|
|
|
|
|
map(tag_no_case("CONTAINSNOT"), |_| Operator::NotContain),
|
2020-06-29 15:36:01 +00:00
|
|
|
|
map(tag_no_case("CONTAINS"), |_| Operator::Contain),
|
2022-06-28 13:39:07 +00:00
|
|
|
|
map(tag_no_case("ALLINSIDE"), |_| Operator::AllInside),
|
|
|
|
|
map(tag_no_case("ANYINSIDE"), |_| Operator::AnyInside),
|
|
|
|
|
map(tag_no_case("NONEINSIDE"), |_| Operator::NoneInside),
|
|
|
|
|
map(tag_no_case("NOTINSIDE"), |_| Operator::NotInside),
|
2020-06-29 15:36:01 +00:00
|
|
|
|
map(tag_no_case("INSIDE"), |_| Operator::Inside),
|
2022-04-29 20:41:57 +00:00
|
|
|
|
map(tag_no_case("OUTSIDE"), |_| Operator::Outside),
|
2020-06-29 15:36:01 +00:00
|
|
|
|
map(tag_no_case("INTERSECTS"), |_| Operator::Intersects),
|
2022-12-18 18:14:07 +00:00
|
|
|
|
map(tag_no_case("NOT IN"), |_| Operator::NotInside),
|
|
|
|
|
map(tag_no_case("IN"), |_| Operator::Inside),
|
2020-06-29 15:36:01 +00:00
|
|
|
|
)),
|
2022-01-13 17:36:41 +00:00
|
|
|
|
))(i)?;
|
|
|
|
|
let (i, _) = shouldbespace(i)?;
|
|
|
|
|
Ok((i, v))
|
2020-06-29 15:36:01 +00:00
|
|
|
|
}
|