vortex_array/scalar_fn/fns/
operators.rs1use core::fmt;
5use std::fmt::Display;
6use std::fmt::Formatter;
7
8use vortex_error::VortexError;
9
10use crate::proto::expr::binary_opts::BinaryOp;
11
12#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Hash)]
18#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
19pub enum Operator {
20 Eq,
22 NotEq,
24 Gt,
26 Gte,
28 Lt,
30 Lte,
32 And,
35 Or,
38 Add,
42 Sub,
48 Mul,
50 Div,
52}
53
54impl From<Operator> for i32 {
55 fn from(value: Operator) -> Self {
56 let op: BinaryOp = value.into();
57 op.into()
58 }
59}
60
61impl From<Operator> for BinaryOp {
62 fn from(value: Operator) -> Self {
63 match value {
64 Operator::Eq => BinaryOp::Eq,
65 Operator::NotEq => BinaryOp::NotEq,
66 Operator::Gt => BinaryOp::Gt,
67 Operator::Gte => BinaryOp::Gte,
68 Operator::Lt => BinaryOp::Lt,
69 Operator::Lte => BinaryOp::Lte,
70 Operator::And => BinaryOp::And,
71 Operator::Or => BinaryOp::Or,
72 Operator::Add => BinaryOp::Add,
73 Operator::Sub => BinaryOp::Sub,
74 Operator::Mul => BinaryOp::Mul,
75 Operator::Div => BinaryOp::Div,
76 }
77 }
78}
79
80impl TryFrom<i32> for Operator {
81 type Error = VortexError;
82
83 fn try_from(value: i32) -> Result<Self, Self::Error> {
84 Ok(BinaryOp::try_from(value)?.into())
85 }
86}
87
88impl From<BinaryOp> for Operator {
89 fn from(value: BinaryOp) -> Self {
90 match value {
91 BinaryOp::Eq => Operator::Eq,
92 BinaryOp::NotEq => Operator::NotEq,
93 BinaryOp::Gt => Operator::Gt,
94 BinaryOp::Gte => Operator::Gte,
95 BinaryOp::Lt => Operator::Lt,
96 BinaryOp::Lte => Operator::Lte,
97 BinaryOp::And => Operator::And,
98 BinaryOp::Or => Operator::Or,
99 BinaryOp::Add => Operator::Add,
100 BinaryOp::Sub => Operator::Sub,
101 BinaryOp::Mul => Operator::Mul,
102 BinaryOp::Div => Operator::Div,
103 }
104 }
105}
106
107impl Display for Operator {
108 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
109 let display = match &self {
110 Operator::Eq => "=",
111 Operator::NotEq => "!=",
112 Operator::Gt => ">",
113 Operator::Gte => ">=",
114 Operator::Lt => "<",
115 Operator::Lte => "<=",
116 Operator::And => "and",
117 Operator::Or => "or",
118 Operator::Add => "+",
119 Operator::Sub => "-",
120 Operator::Mul => "*",
121 Operator::Div => "/",
122 };
123 Display::fmt(display, f)
124 }
125}
126
127impl Operator {
128 pub fn inverse(self) -> Option<Self> {
129 match self {
130 Operator::Eq => Some(Operator::NotEq),
131 Operator::NotEq => Some(Operator::Eq),
132 Operator::Gt => Some(Operator::Lte),
133 Operator::Gte => Some(Operator::Lt),
134 Operator::Lt => Some(Operator::Gte),
135 Operator::Lte => Some(Operator::Gt),
136 Operator::And
137 | Operator::Or
138 | Operator::Add
139 | Operator::Sub
140 | Operator::Mul
141 | Operator::Div => None,
142 }
143 }
144
145 pub fn logical_inverse(self) -> Option<Self> {
146 match self {
147 Operator::And => Some(Operator::Or),
148 Operator::Or => Some(Operator::And),
149 _ => None,
150 }
151 }
152
153 pub fn swap(self) -> Option<Self> {
155 match self {
156 Operator::Eq => Some(Operator::Eq),
157 Operator::NotEq => Some(Operator::NotEq),
158 Operator::Gt => Some(Operator::Lt),
159 Operator::Gte => Some(Operator::Lte),
160 Operator::Lt => Some(Operator::Gt),
161 Operator::Lte => Some(Operator::Gte),
162 Operator::And => Some(Operator::And),
163 Operator::Or => Some(Operator::Or),
164 Operator::Add => Some(Operator::Add),
165 Operator::Mul => Some(Operator::Mul),
166 Operator::Sub | Operator::Div => None,
167 }
168 }
169
170 pub fn is_arithmetic(&self) -> bool {
171 matches!(self, Self::Add | Self::Sub | Self::Mul | Self::Div)
172 }
173
174 pub fn is_comparison(&self) -> bool {
175 self.to_compare_operator().is_some()
176 }
177
178 pub fn to_compare_operator(self) -> Option<CompareOperator> {
183 match self {
184 Operator::Eq => Some(CompareOperator::Eq),
185 Operator::NotEq => Some(CompareOperator::NotEq),
186 Operator::Gt => Some(CompareOperator::Gt),
187 Operator::Gte => Some(CompareOperator::Gte),
188 Operator::Lt => Some(CompareOperator::Lt),
189 Operator::Lte => Some(CompareOperator::Lte),
190 Operator::And
191 | Operator::Or
192 | Operator::Add
193 | Operator::Sub
194 | Operator::Mul
195 | Operator::Div => None,
196 }
197 }
198}
199
200#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Hash)]
203#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
204pub enum CompareOperator {
205 Eq,
207 NotEq,
209 Gt,
211 Gte,
213 Lt,
215 Lte,
217}
218
219impl CompareOperator {
220 pub fn inverse(self) -> Self {
222 match self {
223 CompareOperator::Eq => CompareOperator::NotEq,
224 CompareOperator::NotEq => CompareOperator::Eq,
225 CompareOperator::Gt => CompareOperator::Lte,
226 CompareOperator::Gte => CompareOperator::Lt,
227 CompareOperator::Lt => CompareOperator::Gte,
228 CompareOperator::Lte => CompareOperator::Gt,
229 }
230 }
231
232 pub fn swap(self) -> Self {
234 match self {
235 CompareOperator::Eq => CompareOperator::Eq,
236 CompareOperator::NotEq => CompareOperator::NotEq,
237 CompareOperator::Gt => CompareOperator::Lt,
238 CompareOperator::Gte => CompareOperator::Lte,
239 CompareOperator::Lt => CompareOperator::Gt,
240 CompareOperator::Lte => CompareOperator::Gte,
241 }
242 }
243}
244
245impl Display for CompareOperator {
246 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
247 let display = match self {
248 CompareOperator::Eq => "=",
249 CompareOperator::NotEq => "!=",
250 CompareOperator::Gt => ">",
251 CompareOperator::Gte => ">=",
252 CompareOperator::Lt => "<",
253 CompareOperator::Lte => "<=",
254 };
255 Display::fmt(display, f)
256 }
257}
258
259impl From<CompareOperator> for Operator {
260 fn from(value: CompareOperator) -> Self {
261 match value {
262 CompareOperator::Eq => Operator::Eq,
263 CompareOperator::NotEq => Operator::NotEq,
264 CompareOperator::Gt => Operator::Gt,
265 CompareOperator::Gte => Operator::Gte,
266 CompareOperator::Lt => Operator::Lt,
267 CompareOperator::Lte => Operator::Lte,
268 }
269 }
270}
271
272impl TryFrom<Operator> for CompareOperator {
273 type Error = VortexError;
274
275 fn try_from(value: Operator) -> Result<Self, Self::Error> {
276 value.to_compare_operator().ok_or_else(
277 || vortex_error::vortex_err!(InvalidArgument: "{value} is not a comparison operator"),
278 )
279 }
280}
281
282#[cfg(feature = "arbitrary")]
283impl<'a> arbitrary::Arbitrary<'a> for CompareOperator {
284 fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
285 Ok(match u.int_in_range(0..=5)? {
286 0 => CompareOperator::Eq,
287 1 => CompareOperator::NotEq,
288 2 => CompareOperator::Gt,
289 3 => CompareOperator::Gte,
290 4 => CompareOperator::Lt,
291 5 => CompareOperator::Lte,
292 _ => unreachable!(),
293 })
294 }
295}