vortex_array/scalar_fn/fns/
operators.rs1use core::fmt;
5use std::fmt::Display;
6use std::fmt::Formatter;
7
8use vortex_error::VortexError;
9use vortex_proto::expr::binary_opts::BinaryOp;
10
11#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Hash)]
17#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
18pub enum Operator {
19 Eq,
21 NotEq,
23 Gt,
25 Gte,
27 Lt,
29 Lte,
31 And,
34 Or,
37 Add,
41 Sub,
47 Mul,
49 Div,
51}
52
53impl From<Operator> for i32 {
54 fn from(value: Operator) -> Self {
55 let op: BinaryOp = value.into();
56 op.into()
57 }
58}
59
60impl From<Operator> for BinaryOp {
61 fn from(value: Operator) -> Self {
62 match value {
63 Operator::Eq => BinaryOp::Eq,
64 Operator::NotEq => BinaryOp::NotEq,
65 Operator::Gt => BinaryOp::Gt,
66 Operator::Gte => BinaryOp::Gte,
67 Operator::Lt => BinaryOp::Lt,
68 Operator::Lte => BinaryOp::Lte,
69 Operator::And => BinaryOp::And,
70 Operator::Or => BinaryOp::Or,
71 Operator::Add => BinaryOp::Add,
72 Operator::Sub => BinaryOp::Sub,
73 Operator::Mul => BinaryOp::Mul,
74 Operator::Div => BinaryOp::Div,
75 }
76 }
77}
78
79impl TryFrom<i32> for Operator {
80 type Error = VortexError;
81
82 fn try_from(value: i32) -> Result<Self, Self::Error> {
83 Ok(BinaryOp::try_from(value)?.into())
84 }
85}
86
87impl From<BinaryOp> for Operator {
88 fn from(value: BinaryOp) -> Self {
89 match value {
90 BinaryOp::Eq => Operator::Eq,
91 BinaryOp::NotEq => Operator::NotEq,
92 BinaryOp::Gt => Operator::Gt,
93 BinaryOp::Gte => Operator::Gte,
94 BinaryOp::Lt => Operator::Lt,
95 BinaryOp::Lte => Operator::Lte,
96 BinaryOp::And => Operator::And,
97 BinaryOp::Or => Operator::Or,
98 BinaryOp::Add => Operator::Add,
99 BinaryOp::Sub => Operator::Sub,
100 BinaryOp::Mul => Operator::Mul,
101 BinaryOp::Div => Operator::Div,
102 }
103 }
104}
105
106impl Display for Operator {
107 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
108 let display = match &self {
109 Operator::Eq => "=",
110 Operator::NotEq => "!=",
111 Operator::Gt => ">",
112 Operator::Gte => ">=",
113 Operator::Lt => "<",
114 Operator::Lte => "<=",
115 Operator::And => "and",
116 Operator::Or => "or",
117 Operator::Add => "+",
118 Operator::Sub => "-",
119 Operator::Mul => "*",
120 Operator::Div => "/",
121 };
122 Display::fmt(display, f)
123 }
124}
125
126impl Operator {
127 pub fn inverse(self) -> Option<Self> {
128 match self {
129 Operator::Eq => Some(Operator::NotEq),
130 Operator::NotEq => Some(Operator::Eq),
131 Operator::Gt => Some(Operator::Lte),
132 Operator::Gte => Some(Operator::Lt),
133 Operator::Lt => Some(Operator::Gte),
134 Operator::Lte => Some(Operator::Gt),
135 Operator::And
136 | Operator::Or
137 | Operator::Add
138 | Operator::Sub
139 | Operator::Mul
140 | Operator::Div => None,
141 }
142 }
143
144 pub fn logical_inverse(self) -> Option<Self> {
145 match self {
146 Operator::And => Some(Operator::Or),
147 Operator::Or => Some(Operator::And),
148 _ => None,
149 }
150 }
151
152 pub fn swap(self) -> Option<Self> {
154 match self {
155 Operator::Eq => Some(Operator::Eq),
156 Operator::NotEq => Some(Operator::NotEq),
157 Operator::Gt => Some(Operator::Lt),
158 Operator::Gte => Some(Operator::Lte),
159 Operator::Lt => Some(Operator::Gt),
160 Operator::Lte => Some(Operator::Gte),
161 Operator::And => Some(Operator::And),
162 Operator::Or => Some(Operator::Or),
163 Operator::Add => Some(Operator::Add),
164 Operator::Mul => Some(Operator::Mul),
165 Operator::Sub | Operator::Div => None,
166 }
167 }
168
169 pub fn is_arithmetic(&self) -> bool {
170 matches!(self, Self::Add | Self::Sub | Self::Mul | Self::Div)
171 }
172
173 pub fn is_comparison(&self) -> bool {
174 matches!(
175 self,
176 Self::Eq | Self::NotEq | Self::Gt | Self::Gte | Self::Lt | Self::Lte
177 )
178 }
179}
180
181#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Hash)]
184#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
185pub enum CompareOperator {
186 Eq,
188 NotEq,
190 Gt,
192 Gte,
194 Lt,
196 Lte,
198}
199
200impl CompareOperator {
201 pub fn inverse(self) -> Self {
203 match self {
204 CompareOperator::Eq => CompareOperator::NotEq,
205 CompareOperator::NotEq => CompareOperator::Eq,
206 CompareOperator::Gt => CompareOperator::Lte,
207 CompareOperator::Gte => CompareOperator::Lt,
208 CompareOperator::Lt => CompareOperator::Gte,
209 CompareOperator::Lte => CompareOperator::Gt,
210 }
211 }
212
213 pub fn swap(self) -> Self {
215 match self {
216 CompareOperator::Eq => CompareOperator::Eq,
217 CompareOperator::NotEq => CompareOperator::NotEq,
218 CompareOperator::Gt => CompareOperator::Lt,
219 CompareOperator::Gte => CompareOperator::Lte,
220 CompareOperator::Lt => CompareOperator::Gt,
221 CompareOperator::Lte => CompareOperator::Gte,
222 }
223 }
224}
225
226impl Display for CompareOperator {
227 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
228 let display = match self {
229 CompareOperator::Eq => "=",
230 CompareOperator::NotEq => "!=",
231 CompareOperator::Gt => ">",
232 CompareOperator::Gte => ">=",
233 CompareOperator::Lt => "<",
234 CompareOperator::Lte => "<=",
235 };
236 Display::fmt(display, f)
237 }
238}
239
240impl From<CompareOperator> for Operator {
241 fn from(value: CompareOperator) -> Self {
242 match value {
243 CompareOperator::Eq => Operator::Eq,
244 CompareOperator::NotEq => Operator::NotEq,
245 CompareOperator::Gt => Operator::Gt,
246 CompareOperator::Gte => Operator::Gte,
247 CompareOperator::Lt => Operator::Lt,
248 CompareOperator::Lte => Operator::Lte,
249 }
250 }
251}
252
253impl TryFrom<Operator> for CompareOperator {
254 type Error = VortexError;
255
256 fn try_from(value: Operator) -> Result<Self, Self::Error> {
257 match value {
258 Operator::Eq => Ok(CompareOperator::Eq),
259 Operator::NotEq => Ok(CompareOperator::NotEq),
260 Operator::Gt => Ok(CompareOperator::Gt),
261 Operator::Gte => Ok(CompareOperator::Gte),
262 Operator::Lt => Ok(CompareOperator::Lt),
263 Operator::Lte => Ok(CompareOperator::Lte),
264 other => Err(vortex_error::vortex_err!(
265 InvalidArgument: "{other} is not a comparison operator"
266 )),
267 }
268 }
269}