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 matches!(
176 self,
177 Self::Eq | Self::NotEq | Self::Gt | Self::Gte | Self::Lt | Self::Lte
178 )
179 }
180}
181
182#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Hash)]
185#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
186pub enum CompareOperator {
187 Eq,
189 NotEq,
191 Gt,
193 Gte,
195 Lt,
197 Lte,
199}
200
201impl CompareOperator {
202 pub fn inverse(self) -> Self {
204 match self {
205 CompareOperator::Eq => CompareOperator::NotEq,
206 CompareOperator::NotEq => CompareOperator::Eq,
207 CompareOperator::Gt => CompareOperator::Lte,
208 CompareOperator::Gte => CompareOperator::Lt,
209 CompareOperator::Lt => CompareOperator::Gte,
210 CompareOperator::Lte => CompareOperator::Gt,
211 }
212 }
213
214 pub fn swap(self) -> Self {
216 match self {
217 CompareOperator::Eq => CompareOperator::Eq,
218 CompareOperator::NotEq => CompareOperator::NotEq,
219 CompareOperator::Gt => CompareOperator::Lt,
220 CompareOperator::Gte => CompareOperator::Lte,
221 CompareOperator::Lt => CompareOperator::Gt,
222 CompareOperator::Lte => CompareOperator::Gte,
223 }
224 }
225}
226
227impl Display for CompareOperator {
228 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
229 let display = match self {
230 CompareOperator::Eq => "=",
231 CompareOperator::NotEq => "!=",
232 CompareOperator::Gt => ">",
233 CompareOperator::Gte => ">=",
234 CompareOperator::Lt => "<",
235 CompareOperator::Lte => "<=",
236 };
237 Display::fmt(display, f)
238 }
239}
240
241impl From<CompareOperator> for Operator {
242 fn from(value: CompareOperator) -> Self {
243 match value {
244 CompareOperator::Eq => Operator::Eq,
245 CompareOperator::NotEq => Operator::NotEq,
246 CompareOperator::Gt => Operator::Gt,
247 CompareOperator::Gte => Operator::Gte,
248 CompareOperator::Lt => Operator::Lt,
249 CompareOperator::Lte => Operator::Lte,
250 }
251 }
252}
253
254impl TryFrom<Operator> for CompareOperator {
255 type Error = VortexError;
256
257 fn try_from(value: Operator) -> Result<Self, Self::Error> {
258 match value {
259 Operator::Eq => Ok(CompareOperator::Eq),
260 Operator::NotEq => Ok(CompareOperator::NotEq),
261 Operator::Gt => Ok(CompareOperator::Gt),
262 Operator::Gte => Ok(CompareOperator::Gte),
263 Operator::Lt => Ok(CompareOperator::Lt),
264 Operator::Lte => Ok(CompareOperator::Lte),
265 other => Err(vortex_error::vortex_err!(
266 InvalidArgument: "{other} is not a comparison operator"
267 )),
268 }
269 }
270}
271
272#[cfg(feature = "arbitrary")]
273impl<'a> arbitrary::Arbitrary<'a> for CompareOperator {
274 fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
275 Ok(match u.int_in_range(0..=5)? {
276 0 => CompareOperator::Eq,
277 1 => CompareOperator::NotEq,
278 2 => CompareOperator::Gt,
279 3 => CompareOperator::Gte,
280 4 => CompareOperator::Lt,
281 5 => CompareOperator::Lte,
282 _ => unreachable!(),
283 })
284 }
285}