1use std::fmt;
19
20#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Hash)]
22pub enum Operator {
23 Eq,
25 NotEq,
27 Lt,
29 LtEq,
31 Gt,
33 GtEq,
35 Plus,
37 Minus,
39 Multiply,
41 Divide,
43 Modulo,
45 And,
47 Or,
49 IsDistinctFrom,
53 IsNotDistinctFrom,
57 RegexMatch,
59 RegexIMatch,
61 RegexNotMatch,
63 RegexNotIMatch,
65 LikeMatch,
67 ILikeMatch,
69 NotLikeMatch,
71 NotILikeMatch,
73 BitwiseAnd,
75 BitwiseOr,
77 BitwiseXor,
79 BitwiseShiftRight,
81 BitwiseShiftLeft,
83 StringConcat,
85 AtArrow,
87 ArrowAt,
89}
90
91impl Operator {
92 pub fn negate(&self) -> Option<Operator> {
95 match self {
96 Operator::Eq => Some(Operator::NotEq),
97 Operator::NotEq => Some(Operator::Eq),
98 Operator::Lt => Some(Operator::GtEq),
99 Operator::LtEq => Some(Operator::Gt),
100 Operator::Gt => Some(Operator::LtEq),
101 Operator::GtEq => Some(Operator::Lt),
102 Operator::IsDistinctFrom => Some(Operator::IsNotDistinctFrom),
103 Operator::IsNotDistinctFrom => Some(Operator::IsDistinctFrom),
104 Operator::LikeMatch => Some(Operator::NotLikeMatch),
105 Operator::ILikeMatch => Some(Operator::NotILikeMatch),
106 Operator::NotLikeMatch => Some(Operator::LikeMatch),
107 Operator::NotILikeMatch => Some(Operator::ILikeMatch),
108 Operator::Plus
109 | Operator::Minus
110 | Operator::Multiply
111 | Operator::Divide
112 | Operator::Modulo
113 | Operator::And
114 | Operator::Or
115 | Operator::RegexMatch
116 | Operator::RegexIMatch
117 | Operator::RegexNotMatch
118 | Operator::RegexNotIMatch
119 | Operator::BitwiseAnd
120 | Operator::BitwiseOr
121 | Operator::BitwiseXor
122 | Operator::BitwiseShiftRight
123 | Operator::BitwiseShiftLeft
124 | Operator::StringConcat
125 | Operator::AtArrow
126 | Operator::ArrowAt => None,
127 }
128 }
129
130 pub fn is_numerical_operators(&self) -> bool {
135 matches!(
136 self,
137 Operator::Plus
138 | Operator::Minus
139 | Operator::Multiply
140 | Operator::Divide
141 | Operator::Modulo
142 )
143 }
144
145 pub fn supports_propagation(&self) -> bool {
150 matches!(
151 self,
152 Operator::Eq
153 | Operator::NotEq
154 | Operator::Lt
155 | Operator::LtEq
156 | Operator::Gt
157 | Operator::GtEq
158 | Operator::IsDistinctFrom
159 | Operator::IsNotDistinctFrom
160 | Operator::RegexMatch
161 | Operator::RegexIMatch
162 | Operator::RegexNotMatch
163 | Operator::RegexNotIMatch
164 )
165 }
166
167 #[deprecated(since = "43.0.0", note = "please use `supports_propagation` instead")]
172 pub fn is_comparison_operator(&self) -> bool {
173 self.supports_propagation()
174 }
175
176 pub fn is_logic_operator(&self) -> bool {
181 matches!(self, Operator::And | Operator::Or)
182 }
183
184 pub fn swap(&self) -> Option<Operator> {
188 match self {
189 Operator::Eq => Some(Operator::Eq),
190 Operator::NotEq => Some(Operator::NotEq),
191 Operator::Lt => Some(Operator::Gt),
192 Operator::LtEq => Some(Operator::GtEq),
193 Operator::Gt => Some(Operator::Lt),
194 Operator::GtEq => Some(Operator::LtEq),
195 Operator::AtArrow => Some(Operator::ArrowAt),
196 Operator::ArrowAt => Some(Operator::AtArrow),
197 Operator::IsDistinctFrom
198 | Operator::IsNotDistinctFrom
199 | Operator::Plus
200 | Operator::Minus
201 | Operator::Multiply
202 | Operator::Divide
203 | Operator::Modulo
204 | Operator::And
205 | Operator::Or
206 | Operator::RegexMatch
207 | Operator::RegexIMatch
208 | Operator::RegexNotMatch
209 | Operator::RegexNotIMatch
210 | Operator::LikeMatch
211 | Operator::ILikeMatch
212 | Operator::NotLikeMatch
213 | Operator::NotILikeMatch
214 | Operator::BitwiseAnd
215 | Operator::BitwiseOr
216 | Operator::BitwiseXor
217 | Operator::BitwiseShiftRight
218 | Operator::BitwiseShiftLeft
219 | Operator::StringConcat => None,
220 }
221 }
222
223 pub fn precedence(&self) -> u8 {
226 match self {
227 Operator::Or => 5,
228 Operator::And => 10,
229 Operator::Eq | Operator::NotEq | Operator::LtEq | Operator::GtEq => 15,
230 Operator::Lt | Operator::Gt => 20,
231 Operator::LikeMatch
232 | Operator::NotLikeMatch
233 | Operator::ILikeMatch
234 | Operator::NotILikeMatch => 25,
235 Operator::IsDistinctFrom
236 | Operator::IsNotDistinctFrom
237 | Operator::RegexMatch
238 | Operator::RegexNotMatch
239 | Operator::RegexIMatch
240 | Operator::RegexNotIMatch
241 | Operator::BitwiseAnd
242 | Operator::BitwiseOr
243 | Operator::BitwiseShiftLeft
244 | Operator::BitwiseShiftRight
245 | Operator::BitwiseXor
246 | Operator::StringConcat
247 | Operator::AtArrow
248 | Operator::ArrowAt => 30,
249 Operator::Plus | Operator::Minus => 40,
250 Operator::Multiply | Operator::Divide | Operator::Modulo => 45,
251 }
252 }
253}
254
255impl fmt::Display for Operator {
256 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
257 let display = match &self {
258 Operator::Eq => "=",
259 Operator::NotEq => "!=",
260 Operator::Lt => "<",
261 Operator::LtEq => "<=",
262 Operator::Gt => ">",
263 Operator::GtEq => ">=",
264 Operator::Plus => "+",
265 Operator::Minus => "-",
266 Operator::Multiply => "*",
267 Operator::Divide => "/",
268 Operator::Modulo => "%",
269 Operator::And => "AND",
270 Operator::Or => "OR",
271 Operator::RegexMatch => "~",
272 Operator::RegexIMatch => "~*",
273 Operator::RegexNotMatch => "!~",
274 Operator::RegexNotIMatch => "!~*",
275 Operator::LikeMatch => "~~",
276 Operator::ILikeMatch => "~~*",
277 Operator::NotLikeMatch => "!~~",
278 Operator::NotILikeMatch => "!~~*",
279 Operator::IsDistinctFrom => "IS DISTINCT FROM",
280 Operator::IsNotDistinctFrom => "IS NOT DISTINCT FROM",
281 Operator::BitwiseAnd => "&",
282 Operator::BitwiseOr => "|",
283 Operator::BitwiseXor => "BIT_XOR",
284 Operator::BitwiseShiftRight => ">>",
285 Operator::BitwiseShiftLeft => "<<",
286 Operator::StringConcat => "||",
287 Operator::AtArrow => "@>",
288 Operator::ArrowAt => "<@",
289 };
290 write!(f, "{display}")
291 }
292}