1use crate::idx::ft::MatchRef;
2use crate::sql::index::Distance;
3use revision::revisioned;
4use serde::{Deserialize, Serialize};
5use std::fmt;
6use std::fmt::Write;
7
8#[revisioned(revision = 2)]
10#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
11#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
12#[non_exhaustive]
13pub enum Operator {
14 Neg, Not, Or, And, Tco, Nco, Add, Sub, Mul, Div, Pow, Inc, Dec, Ext, Equal, Exact, NotEqual, AllEqual, AnyEqual, Like, NotLike, AllLike, AnyLike, Matches(Option<MatchRef>), LessThan, LessThanOrEqual, MoreThan, MoreThanOrEqual, Contain, NotContain, ContainAll, ContainAny, ContainNone, Inside, NotInside, AllInside, AnyInside, NoneInside, Outside,
61 Intersects,
62 Knn(u32, Option<Distance>), #[revision(start = 2)]
65 Ann(u32, u32), Rem, }
69
70impl Default for Operator {
71 fn default() -> Self {
72 Self::Equal
73 }
74}
75
76impl Operator {
77 #[inline]
78 pub fn precedence(&self) -> u8 {
79 match self {
80 Self::Or => 1,
81 Self::And => 2,
82 Self::Tco => 3,
83 Self::Nco => 4,
84 Self::Sub => 6,
85 Self::Add => 7,
86 Self::Mul => 8,
87 Self::Div => 9,
88 Self::Rem => 10,
89 _ => 5,
90 }
91 }
92}
93
94impl fmt::Display for Operator {
95 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
96 match self {
97 Self::Neg => f.write_str("-"),
98 Self::Not => f.write_str("!"),
99 Self::Or => f.write_str("OR"),
100 Self::And => f.write_str("AND"),
101 Self::Tco => f.write_str("?:"),
102 Self::Nco => f.write_str("??"),
103 Self::Add => f.write_str("+"),
104 Self::Sub => f.write_char('-'),
105 Self::Mul => f.write_char('*'),
106 Self::Div => f.write_char('/'),
107 Self::Rem => f.write_char('%'),
108 Self::Pow => f.write_str("**"),
109 Self::Inc => f.write_str("+="),
110 Self::Dec => f.write_str("-="),
111 Self::Ext => f.write_str("+?="),
112 Self::Equal => f.write_char('='),
113 Self::Exact => f.write_str("=="),
114 Self::NotEqual => f.write_str("!="),
115 Self::AllEqual => f.write_str("*="),
116 Self::AnyEqual => f.write_str("?="),
117 Self::Like => f.write_char('~'),
118 Self::NotLike => f.write_str("!~"),
119 Self::AllLike => f.write_str("*~"),
120 Self::AnyLike => f.write_str("?~"),
121 Self::LessThan => f.write_char('<'),
122 Self::LessThanOrEqual => f.write_str("<="),
123 Self::MoreThan => f.write_char('>'),
124 Self::MoreThanOrEqual => f.write_str(">="),
125 Self::Contain => f.write_str("CONTAINS"),
126 Self::NotContain => f.write_str("CONTAINSNOT"),
127 Self::ContainAll => f.write_str("CONTAINSALL"),
128 Self::ContainAny => f.write_str("CONTAINSANY"),
129 Self::ContainNone => f.write_str("CONTAINSNONE"),
130 Self::Inside => f.write_str("INSIDE"),
131 Self::NotInside => f.write_str("NOTINSIDE"),
132 Self::AllInside => f.write_str("ALLINSIDE"),
133 Self::AnyInside => f.write_str("ANYINSIDE"),
134 Self::NoneInside => f.write_str("NONEINSIDE"),
135 Self::Outside => f.write_str("OUTSIDE"),
136 Self::Intersects => f.write_str("INTERSECTS"),
137 Self::Matches(reference) => {
138 if let Some(r) = reference {
139 write!(f, "@{r}@")
140 } else {
141 f.write_str("@@")
142 }
143 }
144 Self::Knn(k, dist) => {
145 if let Some(d) = dist {
146 write!(f, "<|{k},{d}|>")
147 } else {
148 write!(f, "<|{k}|>")
149 }
150 }
151 Self::Ann(k, ef) => {
152 write!(f, "<|{k},{ef}|>")
153 }
154 }
155 }
156}